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中的内容,比较麻烦

相关内容

热门资讯

“国补”继续!10月将下达第四... 8月1日国家发展改革委召开新闻发布会,解读当前经济形势和经济工作。国家发展改革委政策研究室有关负责人...
港股IPO,重大调整! 8月1日,港交所就优化首次公开招股市场定价及公开市场规定的咨询文件刊发咨询总结,并就持续优化公众持股...
两江新区:148家智慧医疗装备... 近日,江小妹获悉, 2025年上半年, 作为重庆高新产业的“主阵地”, 两江新区生命健康产业增长势头...
造纸江湖浮沉:废纸回收价5年内... 本报(chinatimes.net.cn)记者何一华 李未来 北京报道 “最近收废纸的价格涨了,以前...
国邦医药已累计回购538万股公... 8月1日晚间,国邦医药发布公告称,截至7月31日,公司通过集中竞价交易方式累计回购股份537.527...
融资杠杆误区:满仓加杠杆不对,... 融资杠杆作为资本市场中通过借入资金放大投资规模的工具,其核心是借助信用机制扩大交易筹码,在提升资金使...
“反内卷”的风吹到了惠民保 记者 姜鑫 7月31日晚,国家金融监督管理总局办公厅发布了《关于推动城市商业医疗险高质量发展的通知》...
酒类即时零售调查:市场规模突破... 出品|搜狐财经 作者|饶婷 编辑|李文贤 【编者按】当数字浪潮席卷消费市场,酒业的 “触网” 之路早...
股票行情快报:赫美集团(002... 证券之星消息,截至2025年8月1日收盘,赫美集团(002356)报收于3.2元,上涨0.31%,换...
刘庆峰说马斯克不懂AI:科大讯... 文:互联网江湖 刘致呈 敢直言马斯克不懂AI的人,出现了。 最近,科大讯飞董事长刘庆峰在与正和岛总...
国债等利息收入增值税恢复征收,... 界面新闻记者 | 杨志锦 界面新闻编辑 | 王姝 财政部、税务总局8月1日发布公告称,自2025...
历史重演?美国7月非农暴雷,美... 来源:第一财经 作为本周最受关注的数据,美国7月非农就业报告意外不及预期,加之此前两个月数据大幅下修...
8月8日起,新发行国债等债券的... 两部门发文恢复征收国债、地方债、金融债券利息收入增值税 财政部、国家税务总局1日联合对外发布公告称,...
首个旧改做地转化宅地 广州市客... 观点网7月31日,广州越秀区挂牌市客运站商住地块,计划于9月1日10时竞价。 该地块位于环市路以南,...
就业引擎熄火,美联储还能“稳住... 来源:市场资讯 来源:汇通网 汇通财经APP讯——7月美国非农就业数据大幅低于预期,仅新增7.3万个...
【公告精选】601088,筹划... 中国神华:筹划发行股份及支付现金购买资产并募集配套资金 股票8月4日起停牌 九号公司:上半年净利12...
原创 一... “老铁们,这周行情像不像坐过山车?指数蔫了吧唧,个股却玩起高空蹦极!南新制药一周暴涨78%,市值差点...
星巴克中国业务竞购名单曝光!腾... 《科创板日报》8月1日讯(记者 徐赐豪),星巴克中国业务的未来发展又有了新变数。 据报道,有知情人士...
带娃去四川三天两夜旅游攻略!成... 我一直梦想着带家人来一场说走就走的旅行,而四川,这个充满魅力的地方,就成了我们的首选。四川不仅有壮丽...
江苏银行:截至目前绿色融资余额... 8月1日,上证报记者从江苏银行获悉,截至目前,该行绿色融资余额已突破7000亿元,服务绿色企业超12...