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

相关内容

热门资讯

黄金闪崩9%!白银跌27%?别... 伦敦金现一天跌9.45%,A股黄金概念股大面积跌停;白银更是单日暴跌26.77%。一夜之间,曾经高歌...
周末这两大重要消息,对2月A股... 刚过去的交易周(1月26日至30日),A股整体呈现放量震荡格局,日均成交额超3万亿元。在大资金持续净...
新任美联储主席提名人选,为什么... 新任美联储主席提名人选终于揭晓。 据新华社报道,美国总统特朗普30日提名美联储前理事凯文·沃什为下任...
上游观察・两会|“十五五”开新... 2月1日上午,2026重庆两会圆满落幕。 回望“十四五”,新重庆交出亮眼答卷——成为中西部地区首个经...
雷军确认一月锁单未交付小米YU... IT之家 2 月 1 日消息,小米今日公布小米 YU7 全新「7 年低息」方案,对于“一月锁单未交付...
项链小红书获客封神攻略!家装人... 做项链饰品的宝子是不是都有同款崩溃:拍100张精修图、写半天文案,笔记互动却个位数;投流花了钱,到店...
SpaceX申请部署100万颗... 大象新闻2026-02-01 10:39:51 据美国《个人电脑杂志》网站1月31日报道,马斯克旗下...
美股点金丨避险情绪升级,美股2... 美股本周尾盘走低,不过三大股指仍以亮眼表现收官1月。下周市场将迎来月度就业报告,外界对货币政策预期可...
肿瘤患者饮食“三不要三要”,吃... 一、饮食“三不要”,避开抗癌饮食坑 1. 不要轻信“饿死癌细胞”:癌细胞会优先抢夺身体营养,盲目节...
宜家在中国败给了谁? 作者 | 会写字的机器猫 来源|新消费智库 图片 | AI生成 新消费导读 上海宝山宜家商场,那个...
证监会拟扩大战略投资者类型并明... 记者1月30日从中国证监会获悉,为贯彻落实《关于推动中长期资金入市的指导意见》和《关于推动中长期资金...
突然大跌!加密货币市值一夜蒸发... 2月1日凌晨,比特币一度跌至75719美元/枚,跌至2025年4月以来的最低水平。截至发稿,比特币回...
刚刚,大跳水!超42万人爆仓!... 来源:券商中国 加密货币,遭遇抛售潮! 凯文·沃什被提名为下一任美联储主席所产生的后续效应,正持续波...
做好银行网点“加减法” 国家金融监督管理总局网站披露的信息显示,2025年共有约1.1万家银行业金融机构的线下网点获准退出,...
金价暴跌引热议,网友:商场门口... 来源:中国基金报 随着国际金价急速下跌,国内首饰金价也迎来大幅回调。 1月31日,老庙报1546元/...
内蒙古一银行员工将储户220万... 内蒙古一银行员工将储户220万元存款转走并挥霍,银行称员工已离岗不愿承担赔偿 1月31日,有媒体报...
老年医学科进修轶事|老年医学如... 和年苑,北京协和医院老年医学科公众号,传递老年医学的价值和声音 在这里,了解当代老年医学 Autum...
和讯投顾余兴栋:周五杀跌,下周... 周五大盘大幅度的杀跌又探底回升,收出一根长长的下影线,不少的朋友又在问我,那这根k线是不是就意味着调...
【数智周报】马化腾评豆包手机;... 【数智周报将整合本周最重要的企业级服务、云计算、大数据领域的前沿趋势、重磅政策及行研报告。】 观点马...