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

  1. 云栖社区>
  2. 博客>
  3. 正文

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

codingcoge 2018-06-05 18:42:55 浏览1208
展开阅读全文

前言:

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();

网友评论

登录后评论
0/500
评论
codingcoge
+ 关注