JAXP

JAXP是一种XML解析规范,JDK6版本引入了Apache Xerces库作为了JAXP的默认实现,该库还实现了XPath表达式处理的API,对于查找XML中的特定数据十分方便。除了Xerces,Dom4J、JDOM也都是流行的XML解析第三方库,但它们不是JAXP标准的,因此在与其它框架结合方面可能出于劣势。这篇笔记我们学习JAXP的使用。

DOM解析和SAX解析

XML文档的解析其实有两种思路,DOM解析和SAX解析。

DOM解析:以文档树形式读取整份XML文档,数据全部载入内存然后由用户解析,特点是速度快、内存占用高,其不仅能用来解析XML,还能在内存创建、修改DOM树以及写入XML文件。

SAX解析:事件驱动的流式XML解析,速度慢但内存占用低,适合嵌入式设备。

DOM解析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接口的内容都很容易理解,上面代码虽然没有列出全部接口的使用方式,但是用到时查阅文档也是十分方便的。

使用XPath定位XML中数据

下面例子在上面代码得到的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表达式章节。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap