使用JAXP进行SAX解析(XMLReaderFactory、XMLReader 、SAXParserFactory与SAXParser)

Java代码审计实战:XXE漏洞原理、挖掘与安全加固指南 XML外部实体注入(XXE)是一种常见的安全漏洞,其原理源于XML解析器默认支持外部实体引用,攻击者可借此读取服务器文件、发起内网请求或导致拒绝服务。在Java开发中,XML广泛应用于数据交换,但许多解析器如DocumentBuilder、SAXParser、DOM4J的SAXReader等默认启用外部实体解析,存在高风险。理解XXE的技术价值在于防范数据泄露与系统入侵,尤其在金融、政务等传统行业系统及微服务API场景中至关重要。本文基于Java代码审计实践,系统剖析XXE漏洞的挖掘路径,涵盖从特征搜索、数 阅读详情

使用JAXP进行SAX解析(XMLReaderFactory、XMLReader 、SAXParserFactory与SAXParser)

  9369人阅读  评论(6)  收藏  举报
  分类:

        SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,遇到符合条件的设定条件后就会触发特定的事件,回调你写好的事件处理程序。使用SAX的优势在于其解析速度较快,相对于DOM而言占用内存较少。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不一定要等文件全部解析完毕。凡事有利必有弊,其劣势在于SAX采用的是流式处理方式,当遇到某个标签的时候,它并不会记录下以前所遇到的标签,也就是说,在处理某个标签的时候,比如在startElement方法中,所能够得到的信息就是标签的名字和属性,至于标签内部的嵌套结构,上层标签、下层标签以及其兄弟节点的名称等等与其结构相关的信息都是不得而知的。实际上就是把XML文件的结构信息丢掉了,如果需要得到这些信息的话,只能你自己在程序里进行处理了。所以相对DOM而言,SAX处理XML文档没有DOM方便,SAX处理的过程相对DOM而言也比较复杂。

        SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

备注说明:SAX API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler, EntityResolver 和 ErrorHandler 

 这里使用最多的就是ContentHandler,仔细阅读 API文档,了解常用方法:startElement、endElement、characters等

 1.startElement方法说明

[java]  view plain  copy
  1. void startElement(String uri,  
  2.                   String localName,  
  3.                   String qName,  
  4.                   Attributes atts)  
  5.                   throws SAXException  
  6. 方法说明:  
  7. 解析器在 XML 文档中的每个元素的开始调用此方法;对于每个 startElement 事件都将有相应的 endElement 事件(即使该元素为空时)。所有元素的内容都将在相应的 endElement 事件之前顺序地报告。  
  8.   
  9. 参数说明:  
  10. uri - 名称空间 URI,如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串  
  11. localName - 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串  
  12. qName - 限定名(带有前缀),如果限定名不可用,则为空字符串  
  13. atts - 连接到元素上的属性。如果没有属性,则它将是空 Attributes 对象。在 startElement 返回后,此对象的值是未定义的  
 2.endElement方法说明

[java]  view plain  copy
  1. void endElement(String uri,  
  2.                 String localName,  
  3.                 String qName)  
  4.                 throws SAXException接收元素结束的通知。   
  5. SAX 解析器会在 XML 文档中每个元素的末尾调用此方法;对于每个 endElement 事件都将有相应的 startElement 事件(即使该元素为空时)。  
  6.   
  7. 参数:  
  8. uri - 名称空间 URI,如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串  
  9. localName - 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串  
  10. qName - 限定的 XML 名称(带前缀),如果限定名不可用,则为空字符串  

3.characters方法

[java]  view plain  copy
  1. void characters(char[] ch,  
  2.                 int start,  
  3.                 int length)  
  4.                 throws SAXException  
  5. 接收字符数据的通知,可以通过new String(ch,start,length)构造器,创建解析出来的字符串文本.  
  6. 参数:  
  7. ch - 来自 XML 文档的字符  
  8. start - 数组中的开始位置  
  9. length - 从数组中读取的字符的个数   

其它方法请参考api数据

下面我们就具体讲解sax解析的操作.

一.我们通过XMLReaderFactory、XMLReader完成,步骤如下

[java]  view plain  copy
  1. 1.通过XMLReaderFactory创建XMLReader对象  
  2. XMLReader reader = XMLReaderFactory.createXMLReader();  
  3. 2. 设置事件处理器对象  
  4. reader.setContentHandler(new MyDefaultHandler());  
  5. 3.读取要解析的xml文件  
  6. FileReader fileReader =new FileReader(new File("src\\sax\\startelement\\web.xml"));  
  7. 4.指定解析的xml文件  
  8. reader.parse(new InputSource(fileReader));  

案例:通过案例对uri、localName、qName和attribute参数有更加深入的了解

1.首先创建要解析的web.xml文件,内容如下

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5"   
  3.     xmlns:csdn="http://java.sun.com/xml/ns/javaee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  6.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  7.   <csdn:display-name></csdn:display-name>     
  8. </web-app>  
  9. <!--   
  10. uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。  
  11. xml namespace-xmlns  
  12. localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。  
  13. qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。  
  14. attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。   
  15.  -->  

2.创建解析测试类及事件处理的内部类代码如下

[java]  view plain  copy
  1. package sax.startelement;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileReader;  
  5.   
  6. import org.junit.Test;  
  7. import org.xml.sax.Attributes;  
  8. import org.xml.sax.InputSource;  
  9. import org.xml.sax.SAXException;  
  10. import org.xml.sax.XMLReader;  
  11. import org.xml.sax.helpers.DefaultHandler;  
  12. import org.xml.sax.helpers.XMLReaderFactory;  
  13.   
  14. public class Demo3 {  
  15.   
  16.     @Test  
  17.     public void test() throws Exception {  
  18.         // 通过XMLReaderFactory创建XMLReader对象  
  19.         XMLReader reader = XMLReaderFactory.createXMLReader();  
  20.         // 设置事件处理器对象  
  21.         reader.setContentHandler(new MyDefaultHandler());  
  22.         // 读取要解析的xml文件  
  23.         FileReader fileReader = new FileReader(new File(  
  24.                 "src\\sax\\startelement\\web.xml"));  
  25.         // 指定解析的xml文件  
  26.         reader.parse(new InputSource(fileReader));  
  27.     }  
  28.   
  29.     // 自定义的解析类,通过此类中的startElement了解uri,localName,qName,Attributes的含义  
  30.     class MyDefaultHandler extends DefaultHandler {  
  31.   
  32.         @Override  
  33.         public void startElement(String uri, String localName, String qName,  
  34.                 Attributes attributes) throws SAXException {  
  35.             super.startElement(uri, localName, qName, attributes);  
  36.             System.out  
  37.                     .println("--------------startElement开始执行--------------------------");  
  38.             System.out.println("uri:::" + uri);  
  39.             System.out.println("localName:::" + localName);  
  40.             System.out.println("qName:::" + qName);  
  41.             for (int i = 0; i < attributes.getLength(); i++) {  
  42.                 String value = attributes.getValue(i);// 获取属性的value值  
  43.                 System.out.println(attributes.getQName(i) + "-----" + value);  
  44.             }  
  45.             System.out  
  46.                     .println("------------------startElement执行完毕---------------------------");  
  47.         }  
  48.   
  49.     }  
  50. }  

3.程序运行的结果如下:


通过运行结果,希望你对uri,localName,qName有更加深入的了解.

二.我们通过SAXParserFactory、SAXParser、XMLReader完成,步骤如下

1.使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
2.通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
3.通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
4.设置读取器的事件处理器
xmlReader.setContentHandler(new BookParserHandler());
5.解析xml文件
xmlReader.parse("book.xml");

说明:如果只是使用SAXParserFactory、SAXParser他们完成只需要如下3步骤

1.获取sax解析器的工厂对象
SAXParserFactory factory = SAXParserFactory.newInstance();
2.通过工厂对象 SAXParser创建解析器对象
SAXParser saxParser = factory.newSAXParser();
3.通过解析saxParser的parse()方法设定解析的文件和自己定义的事件处理器对象
saxParser.parse(new File("src//sax//sida.xml"), new MyDefaultHandler());

案例:解析出"作者"元素标签中的文本内容

1.需要解析的sida.xml文件

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE 四大名著[  
  3. <!ELEMENT 四大名著 (西游记,红楼梦)>  
  4. <!ATTLIST 西游记 id ID #IMPLIED>  
  5. ]>  
  6. <四大名著>  
  7.     <西游记 id="x001">  
  8.         <作者>吴承恩</作者>  
  9.     </西游记>  
  10.     <红楼梦 id="x002">  
  11.         <作者>曹雪芹</作者>  
  12.     </红楼梦>  
  13. </四大名著>  

2.解析测试类和事件处理器类的实现代码

[java]  view plain  copy
  1. package sax;  
  2.   
  3. import java.io.File;  
  4.   
  5. import javax.xml.parsers.SAXParser;  
  6. import javax.xml.parsers.SAXParserFactory;  
  7.   
  8. import org.junit.Test;  
  9. import org.xml.sax.Attributes;  
  10. import org.xml.sax.SAXException;  
  11. import org.xml.sax.helpers.DefaultHandler;  
  12.   
  13. public class SaxTest {  
  14.   
  15.     @Test  
  16.     public void test() throws Exception {  
  17.         // 1.获取sax解析器的工厂对象  
  18.         SAXParserFactory factory = SAXParserFactory.newInstance();  
  19.         // 2.通过工厂对象 SAXParser创建解析器对象  
  20.         SAXParser saxParser = factory.newSAXParser();  
  21.         // 3.通过解析saxParser的parse()方法设定解析的文件和自己定义的事件处理器对象  
  22.         saxParser.parse(new File("src//sax//sida.xml"), new MyDefaultHandler());  
  23.   
  24.     }  
  25.   
  26.     // 自己定义的事件处理器  
  27.     class MyDefaultHandler extends DefaultHandler {  
  28.   
  29.         // 解析标签开始及结束的的标识符  
  30.         boolean isOk = false;  
  31.   
  32.         @Override  
  33.         public void startElement(String uri, String localName, String qName,  
  34.                 Attributes attributes) throws SAXException {  
  35.             super.startElement(uri, localName, qName, attributes);  
  36.             // 当解析作者元素开始的时候,设置isOK为true  
  37.             if ("作者".equals(qName)) {  
  38.                 isOk = true;  
  39.             }  
  40.         }  
  41.   
  42.         @Override  
  43.         public void characters(char[] ch, int start, int length)  
  44.                 throws SAXException {  
  45.             // TODO Auto-generated method stub  
  46.             super.characters(ch, start, length);  
  47.             // 当解析的标识符为true时,打印元素的内容  
  48.             if (isOk) {  
  49.                 System.out.println(new String(ch, start, length));  
  50.             }  
  51.         }  
  52.           
  53.         @Override  
  54.         public void endElement(String uri, String localName, String qName)  
  55.                 throws SAXException {  
  56.             super.endElement(uri, localName, qName);  
  57.             // 当解析作者元素的结束的时候,设置isOK为false  
  58.             if ("作者".equals(qName)) {  
  59.                 isOk = false;  
  60.             }  
  61.         }  
  62.   
  63.     }  
  64. }  

3.程序运行结果如下:


通过以上解析希望你对sax解析有初步的认知.

下面我们也给大家留两个思考题,希望有兴趣的同学可以做一做?

1.sax与Dom解析的区别

2.如果用(二的解析方式解析web.xml)会有什么样的输出结果?怎么解释尼?

顶
2
踩
0
 
 
我的同类文章
猜你在找
Web无障碍——测试与工具
webservice入门到精通(备java基础,xml,javaee框架)
各类接口测试实战合集
XML从入门到精通(备java基础,javaee框架webservice必经之路)
PHP面向对象设计模式
JAVAjava使用XMLReaderFactory类和XMLReader类解析XML文档
SAX之SAXParserFactory与SAXParser
SAX之SAXParserFactory与SAXParser
SAX之SAXParserFactory与SAXParser
使用JAXP进行SAX解析
查看评论
5楼  jhp0921 2015-11-25 20:32发表 [回复]
非常好!请问楼主,saxParser.parse(new File("src//sax//sida.xml"), new MyDefaultHandler()); ,这个方法 第一个参数是 file, 如果是字符串解析呢,因为在后续中已经写好了一系列处理的方法, 但是现在 需要改变xml内容,又不能改文件,只好读到字符串中修改,修改完后 如何解析呢。
4楼  Decting 2015-04-02 08:19发表 [回复]
请问如何才能想第三行说随时终止解析?
3楼  楠之枫雪 2014-10-10 10:46发表 [回复]
说的很好~~~
2楼  skywarmer 2014-08-20 18:27发表 [回复]
sax是以流的形式读取xml文档中的内容,并在读取过程中自动调用预先定义的处理方法;DOM是将整个xml文档中的内容以tree的形式存储在内存当中,可以对这个tree中的任意一个节点进行操作,sax则不能。sax不适合用来修改xml内容,dom需要耗费大量内存。--个人学习心得,大神勿喷。
1楼  wj沧浪之水 2014-08-08 16:06发表 [回复]
讲的非常好
使用SAXParser(SAXParserFactory.newInstance())验证XML文件格式---XSD NULL 博文链接:https://wenhai.iteye.com/blog/563416 立即下载

相关推荐

【机器人】线性方程最小二乘解法对机械臂DH参数进行标定

1.前言 看了一篇文章,觉得里面的DH参数标定法讲的很清晰,便使用Matlab复现了一下,效果还可以,特写此文记录。 2.原理 2.1.误差最佳值的最小二乘计算 有研究结果表明:几乎95%的机器人位置误差都是由机器人内部运动学的不准确描述引起的,所以对DH模型参数进行标定是很有必要的。 DH参数物理含义:选自《机器人学、机器视觉与控制-Matlab基础》 当DH参数确定后,我们...

要恰饭得嘛 1万+

SAXParserFactory解析XML文件

1),person.xml &lt;?xml version="1.0" encoding="UTF-8" ?&gt; &lt;persons&gt; &lt;person&gt; &lt;name&gt;至尊宝&lt;/name&gt; &lt;age&gt;99&lt;/age&gt; &lt;

NULL 7021

清华数据结构列车调度AC100分

两种思路(1)将目标栈的数据和待混洗的数据逐个进行比较#pragma warning(disable:4996) #include&lt;stdio.h&gt; #include&lt;string.h&gt; #define maxn 1600005 using namespace std; char a[2*maxn][5];//记录操作命令 int stack[maxn]; char pop...

hgtjcxy的博客 924

xml.. SAXParserFactory

从文件当中读取 public void parseReadFile(String pathname) {SAXParser parser;SAXParserFactory factory = SAXParserFactory.newInstance();parser = factory.newSAXParser();//有抛出异常File file = new Fi...

weixin_38167363的博客 280

从拆解图看懂空心杯电机:有刷 vs 无刷内部结构全解析(附DIY注意事项)

本文深入解析有刷与无刷空心杯电机的内部结构差异,通过高清拆解图展示关键部件工艺特点,并分享实用的维护技巧和检测方法。重点对比两种电机在效率、寿命和适用场景上的优劣,为DIY爱好者提供详细的注意事项和操作指南。

xgboost6farmer的博客 519

OpenAI Error: 403 Country, region, or territory not supported [Python]

从OpenAI的API服务中获取数据时,由于你所在的国家、地区或领土不被支持,因此请求被拒绝了

suiusoar 5670

sax解析xml,验证格式并支持自定义标签

一、sax简介   SAX是事件驱动型的XML解析方式。顺序读取XML文件,生成事件,传播到用户定义的回调方法中来处理XML文件。   优点:     分段处理xml,而不是将整个xml一次加载进内存,内存占用少,速度快。   缺点:     顺序访问,不能回退。编码复杂,需要用户把控数据结构。 二、使用流程   1.创建工厂 SAXParserFactory saxPa...

weixin_30826095的博客 492

基于转录逆转的药物重定向 GPS 模型

GPS是一个基于分子结构预测基因表达扰动的开源平台,由三个模块组成:RCL(在LINCS扰动数据上训练抗噪MLP)、GPS4Drugs(预测新化合物的基因表达谱并进行逆转评分)、MolSearch(基于MCTS的分子优化)。平台使用Morgan指纹和Gene Ontology注释作为特征输入,将基因表达扰动离散为三分类标签。训练数据来自LINCS Phase I的18,746个化合物和978个landmark基因,支持四细胞系独立训练,可用于药物重定向与化合物筛选。

听雨草堂 83

SAXParserFactory之求解

SAX是Simple API for XML的简称,在Android里面提供对XML文件的解析接口方法,如果给我们一个XML文件,要求把里面我们关心的数据解析出来,我们就可以使用SAX技术,在具体使用中,会对XML文件的每一个字符逐一读取并出发相应事件,也就是说,SAX技术是事件驱动的。比如startDocument,startElement,characters,endElement...

dianhuopao7502的博客 331

数据治理路径之辩:从“先治后用”到“边用边治”,企业如何选择最优路径?

数据治理是企业在数智化建设中的核心挑战,主要涉及三种时序策略:先治理后使用、先用后治理和边用边治。先治理后使用强调在数据应用前建立完整的治理框架,适合高合规要求的行业,但可能响应滞后。先用后治理则优先释放数据价值,适合快速变化的业务环境,但可能累积数据质量问题。边用边治寻求动态平衡,通过持续改进实现治理与应用的同步迭代,适合复杂数据环境。技术选型决策矩阵和实施方法论提供了具体的操作指南,建议根据组织特性和业务需求选择适配方案,并通过渐进式演进路径实现治理与业务的共生演进。

石榴姐yyds 405

AI自动化流程在金融风控中的3个典型案例

AI自动化风控流程全流程自动化:最小化人工干预,实现从数据输入到决策输出的闭环自适应学习:通过持续数据反馈实现模型自动迭代优化实时决策能力:满足毫秒级(支付风控)至分钟级(信贷审批)的响应需求多模态数据融合:整合结构化、非结构化和实时流数据智能决策解释:自动生成符合监管要求的决策解释人机协同机制:在高风险场景下实现AI与人类专家的协同决策实施后关键绩效指标(KPI)变化指标实施前实施后改进幅度平均审批时间3.2天4.7分钟-99.7%自动审批率15%85%+467%

架构师的AI之路,分享AI应用开发架构的学习与实践。 1535

资料参考链接--javaweb

使用JAXP进行SAX解析(XMLReaderFactory、XMLReader 、SAXParserFactory与SAXParser) dom4j官方文档 8.xpath(dom4j支持的jar) 使用xpath新增、查找、删除、上下移动节点 Java8API 参考文档 JAVA的概念理解:JavaSE、JavaEE、JavaME、jdk、jre、ide JRE、JDK、JVM、J...

wuqi5328的博客 306

ssd训练自己的数据集

基于SSD实现目标检测(训练自己的数据集)

reset2021的博客 6804

`org.xml.sax.helpers` 是 Java 标准库中用于简化 SAX(Simple API for XML)解析器开发的辅助类包

`org.xml.sax.helpers` 是 Java 标准库中用于简化 SAX(Simple API for XML)解析器开发的辅助类包,属于 JAXP(Java API for XML Processing)的一部分。该包不包含核心 SAX 接口(如 `ContentHandler`、`XMLReader`),而是提供一系列开箱即用的实用工具类和默认实现,帮助开发者快速构建或扩展 SAX 解析器。

[Blog][Domain] programb.blog.youkuaiyun.com 519

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Android中XML解析之XMLSAXParser解析

Android中XML解析之XMLSAXParser解析 XML解析有几种方式,本文主要介绍XML解析之XMLSAXParser解析。XMLSAXParser解析主要涉及到SAXParserFactory类、SAXParser类和DefaultHandler类。主要使用了工厂方法模式,多例模式,缺省的适配器模式和以及观察者模式。SAXParser解析的静态结构类图,如下: ![SAXParser

何处笙箫 1010

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java XML一口气讲完!(p≧w≦q)

Java SAX XML解析器代表Simple API for XML(SAX)解析器。SAX是一种用于访问XML文档的事件驱动的串行访问机制。此机制经常用于传输和接收XML文档。SAX是一种状态独立处理,其中元素的处理不依赖于其他元素。StAX是状态相关处理。SAX是一个事件驱动模型。当使用SAX解析器时,我们提供了回调方法,并且解析器在读取XML数据时调用它们。在SAX中,我们不能回到文档的早期部分,我们只能处理元素逐个元素,从开始到结束。

爱编程的鱼的博客 1066

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: 使用JAXP进行SAX解析(XMLReaderFactory、XMLReader 、SAXParserFactory与SAXParser)
下一篇: AGCF
javaPie
博客等级 码龄16年 1171粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值