DOM和SAX的解析XML区别

it2023-01-23  52

前言:

XML解析工具

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

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:后三个最重要

void startDocument() : 在读到文档开始时调用void endDocument() :在读到文档结束时调用void startElement(String uri, String localName, String qName, Attributes attributes) : 读到开始标签时调用void endElement(String uri, String localName, String qName) :读到结束标签时调用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)