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

相关内容

热门资讯

不良率上升倒逼防线前移 银行收... 银行正在给个人信贷风控“上强度”。上海证券报记者近期自业内多方了解到,不少银行零售信贷业务从审批权限...
自媒体新手如何快速涨粉?这5个... 自媒体新手如何快速涨粉?这5个技巧让你少走弯路! 嗨,我是小融。 最近很多刚入门自媒体的朋友问我,怎...
乌兰察布市财政局关于黄金领域非... 乌兰察布市财政局关于黄金领域 非法金融活动风险提示 近期,黄金价格波动频繁,市场热度持续攀升,各类假...
一只鸡蛋架“直发”俄罗斯 无锡... (来源:无锡新传媒) 转自:无锡新传媒 一只3D打印塑料鸡蛋架,成为无锡国际邮件互换局正式开通运营后...
武汉楼市开启红五月 新房成交量... 原标题:武汉楼市开启红五月 数据爆表,新房成交量较去年同期翻番 武汉城建未来中心项目营销中心现场来...
一家精神病院竟现身A股公司前十... 5月8日,有投资者发现,盛通股份前十大股东名单中,竟出现了一家精神病院的身影。这家精神病院全称为“上...
真的老了!哈登心魔难除 骑士还... 哈登又拉胯了。 刚刚过去的两场东部半决赛,骑士都输的相当狼狈,而哈登的发挥更是灾难级的。 半决赛G1...
精神病院通报成上市公司前十大股... 近日,上市公司盛通股份发布一季报,披露了前十大股东名单。其中,一家名为“上饶市广丰区十五岭山精神病医...
天溯计量发布年报 上市首年检测... 转自:中国经营网 文 近日,计量检测机构天溯计量(301449.SZ)发布了2025年年度报告。年...
原创 全... 美伊真要停火了? 一页纸协议让全球油价闪崩! 就在今天,全球市场被一条消息炸开了锅。美国白宫觉得,他...
百信银行业绩:26Q1净利润大... 4月底,中信百信银行股份有限公司(下称“百信银行”)2025年财报及2026年一季度报接连披露—— ...
美光科技股价单周飙升38% 市... 【CNMO科技消息】受全球内存芯片短缺影响,美光科技股价本周大幅上涨。截至周五收盘,美光股价报746...
江西一精神病院炒股,炒成上市公... 近日,上市公司盛通股份(002599.SZ)发布一季报,披露了前十大股东名单,其中一家名为“上饶市广...
专访中国太保副总裁俞斌:从“+... 拥抱AI(人工智能),不再是保险行业的“选择题”,而是关乎企业生存与发展的“必答题”,更是企业决胜未...
多平台优化算法:美团取消超时扣... 图片来源:界面图库 5月8日,网信中国发布消息称,生活服务类平台算法治理已取得初步成效,美团、淘宝、...
原创 2... 2025年,国内系统重要性银行名单正式公布。这是我国金融体系的核心支柱,一共21家银行入选,它们是维...
东海县供销总社:“供销+龙头企... 近日,东海县供销合作总社鼎味泰直营店正式开业。作为东海县供销系统打造的新型社企便民服务网点,该门店的...
原创 阿... 深夜,一家零食店铺的客服后台弹出一条消息:“我上次买的芒果干,这次想换个不那么酸的口味,再帮我推荐几...
和平湾全新项目前瞻 负公摊、唯... 在沈阳,如果想在主城核心区域找一块容积率低于1.5的住宅用地,难度有多大? 过去三年,沈阳主城核心区...
精神病院与国际投行高盛同在 盛... 近日,盛通股份(002599.SZ)发布一季报,其前十大股东名单中,第九位为“上饶市广丰区十五岭山精...