SAX解析
创始人
2025-05-28 01:58:52
0

SAX解析

原文链接https://zhhll.icu/2020/xml/SAX/SAX解析/

SAX解析介绍

由于DOM解析XML的弊端,一种替代的技术就是使用SAX解析。

SAX是基于事件模型的XML解析方式,不需要将整个XML文档加载到内存中,只需加载一部分即可开始解析,在处理过程中不会在内存中记录XML中的数据,占用的资源比较少,当程序处理满足一定条件时,可以立即停止解析,这样不必解析剩余的XML内容。

SAX处理机制

SAX解析主要涉及两个部分:解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发送事件,如元素开始和结束事件;事件处理器则负责对事件做出响应,对传递的XML数据进行处理。

当SAX解析器解析到某类型节点时,会触发注册在该类型节点上的回调函数,继承SAX提供的DefaultHandler来重写相应事件的处理方法并进行注册即可。(事件是由解析器产生并通过回调函数发送给应用程序的,这种模式称为推模式)。

SAX接口介绍

  • SAXParserFactory 获取SAX解析器的工厂类
  • SAXParser SAX解析器的标准接口

监听器

SAX解析事件一共有四种监听器

  • EntityResolver 监听实体处理时间的监听器

    public interface EntityResolver {public abstract InputSource resolveEntity (String publicId,String systemId)throws SAXException, IOException;}
    
  • DTDHandler 监听DTD处理事件的监听器

    public interface DTDHandler {// 解析DTD符号时触发public abstract void notationDecl (String name,String publicId,String systemId)throws SAXException;// 解析DTD中的未解析实体时触发public abstract void unparsedEntityDecl (String name,String publicId,String systemId,String notationName)throws SAXException;}
    
  • ContentHandler 监听XML文档内容处理事件的监听器

    public interface ContentHandler
    {public void setDocumentLocator (Locator locator);// 开始处理文档时触发public void startDocument ()throws SAXException;// 处理文档结束时触发public void endDocument()throws SAXException;// 开始处理元素中的命名空间属性时触发(xmlns:prefix属性)public void startPrefixMapping (String prefix, String uri)throws SAXException;// 处理元素中的命名空间属性结束时触发(xmlns:prefix属性)public void endPrefixMapping (String prefix)throws SAXException;// 开始处理元素时触发public void startElement (String uri, String localName,String qName, Attributes atts)throws SAXException;// 处理元素结束时触发public void endElement (String uri, String localName,String qName)throws SAXException;// 处理字符数据时触发public void characters (char ch[], int start, int length)throws SAXException;// 处理元素内容中可忽略的空白时触发public void ignorableWhitespace (char ch[], int start, int length)throws SAXException;// 处理指令时触发public void processingInstruction (String target, String data)throws SAXException;// 跳过实体时触发public void skippedEntity (String name)throws SAXException;
    }
    
  • ErrorHandler 监听解析错误的监听器

    public interface ErrorHandler {public abstract void warning (SAXParseException exception)throws SAXException;public abstract void error (SAXParseException exception)throws SAXException;public abstract void fatalError (SAXParseException exception)throws SAXException;}
    

这么多接口都进行实现那是不是太麻烦了呢,瞬间就不想用SAX来进行解析了,不过JAXP提供了一个类来很好的解决这个问题DefaultHandler,该类实现了这四个接口

public class DefaultHandler implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler

并对这些方法提供了空实现,通常只需要继承该类来重写我们需要关心的监听方法即可

public static SAXParser createDefaultParser(InputStream stream,DefaultHandler handler) throws ParserConfigurationException, SAXException, IOException {SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser =  factory.newSAXParser();parser.parse(stream,handler);return parser;}public static void readMapper(String fileName){InputStream stream = ClassLoader.getSystemResourceAsStream("test.xml");SAXParser parser = null;try {parser = createDefaultParser(stream,new DefaultHandler(){// 当前元素private String currentTag;@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {System.out.println("开始处理元素"+qName);currentTag = qName;int length = attributes.getLength();if(length > 0){System.out.println(currentTag+"元素中包含属性");for(int i = 0;iSystem.out.println(attributes.getQName(i)+"--->"+attributes.getValue(i));}}}@Overridepublic void characters(char[] ch, int start, int length) throws SAXException {String content = new String(ch,start,length);if(content.trim().length() > 0){System.out.println(currentTag+"元素中的值是"+content);}}@Overridepublic void endDocument() throws SAXException {System.out.println("xml解析完毕");}@Overridepublic void startDocument() throws SAXException {System.out.println("开始读取xml文档");}});} catch (ParserConfigurationException | SAXException | IOException e) {throw new RuntimeException("SAX解析器构建失败",e);}}

SAX的缺点

  • 由于不存储XML文档结构,需要开发人员自己负责维护多层节点之间的关系
  • 由于是流式处理,只能单向处理,无法回到之前处理过的节点
  • 不提供写文档的功能

DOM和SAX比较

  • 速度 DOM需要一次性装载整份文档,并将xml文档转为DOM数,速度较慢;SAX顺序解析XML文档,无需一次装载整份文档,速度较快
  • 重复访问 DOM转换为DOM树后,整个解析阶段DOM树常驻内存,非常适合重复访问,效率较高;SAX顺序解析XML文档,不会保存已访问的数据,不适合重复访问,如果需要重复访问需要再次开始解析
  • 内存要求 DOM整个解析阶段DOM树常驻内存,内存占用较多;SAX不保存已访问数据,内存占用低
  • 修改 DOM既可以读取节点内容,也可以修改节点内容;SAX只能用来读取,不可修改
  • 复杂度 DOM完全采用面向对象的思想,整份XML转为DOM树后,以面向对象的方式来操作各个Node对象即可;SAX采用事件驱动的方式,SAX解析器只负责触发事件,程序负责监听事件,并通过事件获取XML中的内容,比较麻烦

相关内容

热门资讯

黄金“不灵了”,高端金饰的溢价... 古法黄金到底能不能走出脱离金价波动的独立溢价 作者:赵心怡 2026年开年,国际金价一路狂飙至近56...
朗迅科技由董事长徐振控制46%... 瑞财经 刘治颖 6月24日,杭州朗迅科技股份有限公司(以下简称:朗迅科技)深主板IPO获受理,保荐机...
两部门:2030年可再生能源制... 【两部门:2030年可再生能源制氢规模达到200万吨】财联社6月25日电,国家发展改革委、国家能源局...
原创 警... 大家好,这里是全球脉冲。 6月16日,日本央行宣布加息25个基点,政策利率上调至1%,创下31年来最...
黄金钻石回收怎么选?上海市场常... 近年来黄金价格持续走高,不少上海市民都有变现家中闲置黄金首饰、投资金条的打算。但市面上回收门店数量众...
专访火山引擎谭待:模型好对Ma... 文 | 邓咏仪 编辑 | 张雨忻 火山引擎总裁谭待 来源:火山引擎 过去三年,火山引擎总裁谭待给团...
女董事长深夜被带走,牵出金融旧... *此图由AI生成 作者| 史大郎&猫哥 来源| 是史大郎&大猫财经Pro 大半夜的,一家上市公司董事...
盯盯拍报考港交所上市:出海翻红... 撰稿|贝多 来源|贝多商业&贝多财经 6月22日,盯盯拍(深圳)技术股份有限公司(下称“盯盯拍”)递...
苏州千亿市值上市公司+1! A股“苏州板块”又诞生了一家千亿市值企业。 昨日(6月25日),苏州上市公司永鼎股份股价在昨日涨停的...
芯片股猛拉!600667,一字... 【导读】创业板指一度涨超2%,存储芯片、半导体、电子元器件等方向涨幅居前 中国基金报记者 李智 一起...
分析师:海峡收费与否已不重要 ... 来源:格隆汇APP 格隆汇6月25日|阿曼方面重申,霍尔木兹海峡未来安排不涉及通行费。美国财经网站i...
《内外贸一体化企业评价通则》团... 齐鲁晚报·齐鲁壹点记者 管悦 6月25日,《内外贸一体化企业评价通则》团体标准审查会在济南召开。该标...
提升AI智能体工作流的速度与能... 智能体工作流是一种由AI驱动的软件系统,它通过串联多个模型与外部工具来处理复杂任务,例如分析视频并回...
热搜!又有纸尿裤被曝检出甲酰胺... 来源:市场资讯 (来源:北京商报) 网友:“囤了200多包”。 近日,多个婴幼儿纸尿裤品牌“被检出...
埃森哲内部录音曝光:企业AI使... IT之家 6 月 26 日消息,科技媒体 404Media 昨日(6 月 25 日)发布博文,披露了...
FIBA期待杨瀚森表现 最新实... 北京时间6月25日消息,FIBA国际篮联公布了最新一期世界杯预选赛亚太区球队实力榜,中国男篮排在澳大...
收评:创业板指放量反弹涨2.8... 市场冲高回落后,再度震荡拉升。黄白线分化明显,权重股走势较强。量能明显放大,沪深两市成交额3.59万...
巨头财报引爆A股存储芯片板块,... 当地时间6月24日美股盘后, 美光科技(MU.US)公布截至5月31日的2026财年第三财季财报,业...
银行、消金公司助贷余额增速不得... 近日,中国证券报记者从多位业内人士处独家获悉,5月以来,多地金融监管部门对部分中小银行、消金公司下达...