XML
因为具有良好的数据描述能力和跨平台性,被广泛应用于数据存储和交换等,比如用作配置文件等。 在日常开发中,我们可能也需要处理 XML数据。这里就来介绍几种在 Java 中常见的对 XML 的处理方法。
使用建议: 推荐直接使用
Dom4j
,若追求性能可尝试SAX
。
DOM
和 SAX
是 Java 提供的基础的处理方法,属于 JAXP
, JDom
和 Dom4j
是建立其上的第三方库。
涉及 | 说明 | 优劣 |
---|---|---|
DOM |
基于 dom树 的处理方式,与平台无关解析方式,遵循 w3c 标准 。 |
以树结构处理数据,操作方便。内存一次性加载 DOM树,不利于大数据量的处理。 |
SAX |
基于事件驱动的处理方式。 | 边读边处理,内存占用小,解析速度快,因为逐行解析不利于随机访问和操作。 |
JDom |
仅使用具体类而不使用接口,API 大量使用 Collection 类。 | 提供的 API 非常利于编码,但性能较弱,存在内存溢出风险。 |
Dom4j |
起源自 JDom 。使用接口和抽象基础类方法。优秀而强大的 API 。 |
易用性和性能兼顾的 API ,成为了许多开源框架的标配处理方式。 |
性能对比
1 | 解析耗时:JDom > DOM > Dom4j >> SAX |
认识 XML
XML (可扩展标记语言)
,一种通用的数据交换格式,由众多节点标签组成,总体呈树结构,可以有效的描述复杂的数据结构。
XML 常见节点类型 | 说明 |
---|---|
document |
文档对象模型 |
element |
标签元素 |
attribute |
属性 |
本文会以此 XML 为例,介绍相关功能的简单使用。
1 | <?xml version="1.0" encoding="UTF-8"?> |
DOM
DOM
会一次性加载将整个 XML,并将其视为dom树
,树由节点构成。
标签、标签之间的间隔内容、属性等都被视为节点 。
节点类型 | nodeType | nodeName | nodeValue |
---|---|---|---|
Element | Node.ELEMENT_NODE |
元素名 | null |
Attr | Node.ATTRIBUTE_NODE |
属性名 | 属性值 |
Text | Node.TEXT_NODE |
#text |
节点内容 |
解析
1 |
|
生成
1 |
|
domTest.xml
1 | <transaction> |
SAX
SAX
使用 Hander
边解析边处理,在对应位置会触发执行对应方法。
Handler 常用方法 | 说明 |
---|---|
startDocument() |
文档开始时触发。 |
endDocument() |
文档结束时触发。 |
startElement(String uri, String localName, String qName, Attributes attributes) |
元素节点开始时触发。 |
endElement(String uri, String localName, String qName) |
元素节点结束时触发。 |
characters(char[] ch, int start, int length) |
可以接收元素内字符数据的方法。 |
解析
1 |
|
ParserHandler
自定义一个 Handler
用于解析处理 ,需要继承 org.xml.sax.helpers.DefaultHandler
。
characters()
可以拿到节点值,但需要注意:
- 和 DOM 一样 空白也被识别为节点。
- 因为
SAX
会将 dom 分块解析 (默认2k),所以直接获取的节点值不一定是完整的。
1 | public class SaxParserHandler extends DefaultHandler { |
生成
1 |
|
saxTest.xml
1 | <transaction id="1"> |
JDom
JDom
的 API 使用集合来存储节点信息,操作起来十分便利。
添加
jdom
依赖,如下:
1 | <dependency> |
解析
1 |
|
生成
1 |
|
jDomTest.xml
1 |
|
Dom4j
Dom4j
中需要通过迭代器来遍历相关信息。
添加
dom4j
依赖,如下:
1 | <dependency> |
解析
1 |
|
生成
1 |
|
dom4jTest.xml
1 |
|