XML的SAX解析以及DOM解析和SAX解析区别

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

前言:

XML解析工具

DOM解析原理:
    1)JAXP (oracle-Sun公司官方)
    2)JDOM工具(非官方)
    3)Dom4J工具(非官方)
    三大框架(默认读取xml的工具就是Dom4j)
    .......

SAX解析原理:
    1)Sax解析工具(oracle-sun公司官方)

老样子,三个问题:

SAX解析是什么?
SAX怎么用?
SAX运用场景?

SAX是什么?

也是用来解析XML的
SAX解析工具- 内置在jdk中。org.xml.sax.*

SAX运用场景?

DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树。
对内存要求比较要。    
缺点: 不适合读取大容量的xml文件,容易导致内存溢出。

SAX解析原理: 加载一点,读取一点,处理一点。对内存要求比较低。

SAX解析工具核心:

核心的API:

SAXParser类: 用于读取和解析xml文件对象
parse(File f, DefaultHandler dh)方法: 解析xml文件

参数一: File:表示 读取的xml文件。

参数二: DefaultHandler: SAX事件处理程序。使用DefaultHandler的子类

第一步:创建对象

    //1.创建SAXParser对象
    SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        
        //2.调用parse方法
        /**
         * 参数一: xml文档
         * 参数二: DefaultHandler的子类   MyDefaultHandler()为自定义
         */
    parser.parse(new File(".\\src\\Go\\person.xml"),  
    new MyDefaultHandler());

注意:
这里创建SAXParser对象 不能直接通过构造函数来创造,因为用到了单例工厂模式。

链接:类 SAXParser的jdk文档

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

所以创建一个SAXParser对象 需要:
SAXParserFactory.newInstance().newSAXParser();

DefaultHandler类的API:后三个最重要

  1. void startDocument() : 在读到文档开始时调用
  1. void endDocument() :在读到文档结束时调用
  2. void startElement(String uri, String localName, String qName, Attributes attributes) :
    读到开始标签时调用
  3. void endElement(String uri, String localName, String qName) :读到结束标签时调用
  4. void characters(char[] ch, int start, int length) : 读到文本内容时调用

第二步:自定义类继承DefaultHandler重写方法

这些都是要重写的 举个例子:

public class MyDefaultHandler extends DefaultHandler {
    
    /**
     * 开始文档时调用
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("MyDefaultHandler.startDocument()");
    }
    
    /**
     * 开始标签时调用
     * @param qName: 表示开始标签的标签名
     * @param attributes: 表示开始标签内包含的属性列表
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("MyDefaultHandler.startElement()-->"+qName);
    }
    
    /**
     * 结束标签时调用
     * @param qName: 结束标签的标签名称
     */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.println("MyDefaultHandler.endElement()-->"+qName);
    }
    
    /**
     * 读到文本内容的时调用
     * @param ch: 表示当前读完的所有文本内容
     * @param start: 表示当前文本内容的开始位置
     * @param length: 表示当前文本内容的长度
     * char[](                                       张三              20)   100
     *                              98 2   
     */ 
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        //得到当前文本内容
        String content = new String(ch,start,length);
        System.out.println("MyDefaultHandler.characters()-->"+content);
    }
    
    /**
     * 结束文档时调用
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("MyDefaultHandler.endDocument()");
    }
    
}

xml样例:

<?xml version="1.0" encoding="utf-8"?>
<contactList>
    <contact id="001" name="eric">
        <name>张三</name>
        <age>20</age>
        <phone>134222223333</phone>
        <email>zhangsan@qq.com</email>
        <qq>432221111</qq>
    </contact>
    <contact id="002" name="jacky">
        <name>eric</name>
        <age>20</age>
        <phone>134222225555</phone>
        <email>lisi@qq.com</email>
        <qq>432222222</qq>
    </contact>
</contactList>

结果:

MyDefaultHandler.startDocument()
MyDefaultHandler.startElement()-->contactList
MyDefaultHandler.characters()-->
    
MyDefaultHandler.startElement()-->contact
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->name
MyDefaultHandler.characters()-->张三
MyDefaultHandler.endElement()-->name
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->age
MyDefaultHandler.characters()-->20
MyDefaultHandler.endElement()-->age
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->phone
MyDefaultHandler.characters()-->134222223333
MyDefaultHandler.endElement()-->phone
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->email
MyDefaultHandler.characters()-->zhangsan@qq.com
MyDefaultHandler.endElement()-->email
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->qq
MyDefaultHandler.characters()-->432221111
MyDefaultHandler.endElement()-->qq
MyDefaultHandler.characters()-->
    
MyDefaultHandler.endElement()-->contact
MyDefaultHandler.characters()-->
    
MyDefaultHandler.startElement()-->contact
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->name
MyDefaultHandler.characters()-->eric
MyDefaultHandler.endElement()-->name
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->age
MyDefaultHandler.characters()-->20
MyDefaultHandler.endElement()-->age
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->phone
MyDefaultHandler.characters()-->134222225555
MyDefaultHandler.endElement()-->phone
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->email
MyDefaultHandler.characters()-->lisi@qq.com
MyDefaultHandler.endElement()-->email
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->qq
MyDefaultHandler.characters()-->432222222
MyDefaultHandler.endElement()-->qq
MyDefaultHandler.characters()-->
    
MyDefaultHandler.endElement()-->contact
MyDefaultHandler.characters()-->

MyDefaultHandler.endElement()-->contactList
MyDefaultHandler.endDocument()

注意:
问题:MyDefaultHandler.characters()-->空白 ?

答:

    <contactList>
    <contact>
    之间也是有文本的 是换行和空格 被characters方法读取了。

来看一下SAX解析XML的流程图:(图片来自传智播客)
回到开头SAX解析原理: 加载一点,读取一点,处理一点。对内存要求比较低。
这里写图片描述


总结:

==================DOM解析 vs SAX解析 ============================

DOM解析 :

原理: 一次性加载xml文档,不适合大容量的文件读取
DOM解析可以任意进行增删改成
DOM解析任意读取任何位置的数据,甚至往回读
DOM解析面向对象的编程方法(Node,Element,Attribute),  
Java开发者编码比较简单。

SAX解析 :

原理: 加载一点,读取一点,处理一点。适合大容量文件的读取
SAX解析只能读取
SAX解析只能从上往下,按顺序读取,不能往回读
SAX解析基于事件的编程方法。java开发编码相对复杂。

XML操作:

            1)Dom4j修改xml文档
                 new XMLWrier();
                    ......
            2)xPath技术: 快速查询xml节点
                    selectNodes()
                    selectSinglNode();    
            3)  SAX解析
                    SAXParser parse
                        parser()
                DefaultHandler类:
                        startElement();
                        characters();
                        endElement();
目录
相关文章
|
6天前
|
XML JavaScript Java
【JAVA XML 探秘】DOM、SAX、StAX:揭秘 Java 中 XML 解析技术的终极指南!
【8月更文挑战第25天】本文详细探讨了Java中三种主流的XML解析技术:DOM、SAX与StAX。DOM将XML文档转换为树状结构,便于全方位访问和修改;SAX采取事件驱动模式,适用于大型文件的顺序处理;StAX则兼具DOM和SAX的优点,支持流式处理和随机访问。文中提供了每种技术的示例代码,帮助读者理解如何在实际项目中应用这些解析方法。
34 1
|
2天前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM 解析器
|
4天前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM解析器是内置在大多数浏览器中的工具,用于读取和操作XML文档。它将XML数据转换成JavaScript可访问的XML DOM对象。DOM提供了一系列方法和函数来遍历、访问、插入和删除XML树的节点。在处理XML文档前,需要先加载它到DOM对象中。示例如下:通过条件判断创建XMLHTTP对象,打开并发送请求获取XML文件内容,最后将服务器响应设置为XML DOM对象以便后续处理。
|
2天前
|
XML 存储 JavaScript
xml介绍与解析,及xml库包使用
xml介绍与解析,及xml库包使用
7 0
|
4天前
|
安全 网络虚拟化 网络架构
|
6天前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM解析器是内置在大多数浏览器中的工具,用于读取和操作XML文档。它将XML数据转换成XML DOM对象,使JavaScript能够访问和处理这些数据。DOM解析器提供了一系列方法来遍历、访问、插入和删除XML树中的节点。为了操作XML文档,首先需要加载文档到DOM对象中。示例代码展示了如何通过XMLHTTP请求加载一个名为&quot;books.xml&quot;的XML文件,并将其设置为XML DOM对象以供后续处理。
|
26天前
|
存储 NoSQL Redis
redis 6源码解析之 object
redis 6源码解析之 object
49 6
|
1天前
|
监控 网络协议 Java
Tomcat源码解析】整体架构组成及核心组件
Tomcat,原名Catalina,是一款优雅轻盈的Web服务器,自4.x版本起扩展了JSP、EL等功能,超越了单纯的Servlet容器范畴。Servlet是Sun公司为Java编程Web应用制定的规范,Tomcat作为Servlet容器,负责构建Request与Response对象,并执行业务逻辑。
Tomcat源码解析】整体架构组成及核心组件
|
9天前
|
测试技术 Python
python自动化测试中装饰器@ddt与@data源码深入解析
综上所述,使用 `@ddt`和 `@data`可以大大简化写作测试用例的过程,让我们能专注于测试逻辑的本身,而无需编写重复的测试方法。通过讲解了 `@ddt`和 `@data`源码的关键部分,我们可以更深入地理解其背后的工作原理。
11 1
|
19天前
|
开发者 Python
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
51 1

推荐镜像

更多
下一篇
云函数