JAXP是一种XML解析规范,JDK6版本引入了Apache Xerces库作为了JAXP的默认实现,该库还实现了XPath表达式处理的API,对于查找XML中的特定数据十分方便。除了Xerces,Dom4J、JDOM也都是流行的XML解析第三方库,但它们不是JAXP标准的,因此在与其它框架结合方面可能出于劣势。这篇笔记我们学习JAXP的使用。
XML文档的解析其实有两种思路,DOM解析和SAX解析。
DOM解析:以文档树形式读取整份XML文档,数据全部载入内存然后由用户解析,特点是速度快、内存占用高,其不仅能用来解析XML,还能在内存创建、修改DOM树以及写入XML文件。
SAX解析:事件驱动的流式XML解析,速度慢但内存占用低,适合嵌入式设备。
使用DOM解析时,首先我们要了解一些DOM解析规范。在JAXP中,整个DOM树结构被称为文档(Document)。每一个XML标签节点,每一个文字节点,都被称为子节点(Node)。XML标签节点还能再次包含子节点,因此被称为元素(Element),Element接口继承于Node接口。文本节点就是一个字符串,因此被称为文本(TEXT),TEXT也继承于Node。
像标签属性是Element独有的,取字符串值则是TEXT独有的,但是一个Node的子节点既有Element也有TEXT,那么遍历的接口子节点类型全部为Node,我们使用的时候就需要通过instanceof
进行判断。
下面我们编写一个例子,使用JAXP解析XML文档。
<?xml version="1.0" encoding="utf-8" ?>
<font>
<name>Source Code Pro</name>
<size unit="pt">35</size>
</font>
package com.gacfox.demo;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
public class Main {
public static void main(String[] args) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("data.xml");
Document document = builder.parse(inputStream);
//获取根节点
Element root = document.getDocumentElement();
//输出节点名字
System.out.println(root.getTagName());
//获取子节点
NodeList children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
//根据索引取得子节点
Node child = children.item(i);
//只获取子标签节点(排除换行符等被识别为文字节点)
if (child instanceof Element) {
//读取文字节点的值
Element childElement = (Element) child;
Text textNode = (Text) childElement.getFirstChild();
System.out.println(textNode.getData().trim());
//读取节点属性值
if (childElement.getTagName().equals("size")) {
System.out.println(childElement.getAttribute("unit"));
}
}
}
} catch (ParserConfigurationException | IOException | SAXException e) {
throw new RuntimeException(e);
}
}
}
JAXP接口的内容都很容易理解,上面代码虽然没有列出全部接口的使用方式,但是用到时查阅文档也是十分方便的。
下面例子在上面代码得到的document
对象基础上实现,我们使用XPath表达式读取了一些XML文档中的信息。
//获取XPath对象
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
//读取文本节点
String sizeValue = xpath.evaluate("/font/size", document);
System.out.println(sizeValue);
//读取节点属性
String sizeAttribute = xpath.evaluate("/font/size/@unit", document);
System.out.println(sizeAttribute);
有关XPath语法更多内容请参考软件开发相关工具/软件开发相关知识/表达式语言/XPath表达式
章节。