Java使用XPath表达式操作XML

版权声明:[email protected] https://blog.csdn.net/zhaoxuyang1997/article/details/82702068

1 XPath简介

XPath之于XML就像SQL语言之于SQL数据库,是一种XML查询语言

1.1 常用的XPath表达式

表达式 含义
nodename 选取指定节点的所有子节点
/ 从根节点选取指定节点
// 根据指定的表达式,在整个文档中选取匹配的节点,不会考虑位置
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
* 匹配任何元素节点
@* 匹配任何属性节点
node() 匹配任何类型的节点
text() 匹配文本节点
| 选取若干路径
[] 指定某个条件,用于查找某个特定节点或包含某个指定值的节点

1.2 XPath示例

例如,在books.xml中查找作者为罗贯中的所有书籍的标题

构造XPath的过程如下:

  1. 查找所有书籍://book
  2. 查找所有作者为罗贯中的书籍://book[author='罗贯中']
  3. 查找所有作者为罗贯中的书籍的标题://book[author='罗贯中']/title
  4. 最后真正需要的是<title>下的文本://book[author='罗贯中']/title/text()

程序会输出:

[#text: 三国演义]
[#text: 水浒传]


例如,在books.xml中查找2001年及以后的所有书籍的标题

//book[@year>=2001]/title/text()

程序会输出:

[#text: 水浒传]
[#text: 西游记]


例如,在books.xml中查找2001年及以后的所有书籍的标题和属性

//book[@year>=2001]/title/text()|//book[@year>=2001]/@*

程序会输出:

year=”2001”
[#text: 水浒传]
year=”2002”
[#text: 西游记]


2 Java 使用XPath表达式操作XML

2.1 XML文件内容

file:///D:/Code/java/DesignPattern/src/com/zxy97/test/xml/dom/books.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book year="2000">
        <title>三国演义</title>
        <author>罗贯中</author>
        <price>29.9</price>
    </book>
    <book year="2001">
        <title>水浒传</title>
        <author>施耐庵</author>
        <price>39.9</price>
    </book>
    <book year="2002">
        <title>西游记</title>
        <author>吴承恩</author>
        <price>29.9</price>
    </book>
</books>

2.2 主程序

file:///D:/Code/java/DesignPattern/src/com/zxy97/test/xml/dom/XPathTest.java

package com.zxy97.test.xml.dom;

import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class XPathTest {
    public static void main(String[] args){
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();//创建DocumentBuilderFactory

            //开启验证
            dbf.setValidating(true);
            dbf.setNamespaceAware(false);
            dbf.setIgnoringComments(false);
            dbf.setIgnoringElementContentWhitespace(false);
            dbf.setCoalescing(false);
            dbf.setExpandEntityReferences(true);

            DocumentBuilder builder = dbf.newDocumentBuilder();//创建DocumentBuilder

            //设置DocumentBuilder的异常处理
            builder.setErrorHandler(new ErrorHandler(){   
                @Override
                public void warning(SAXParseException exception) throws SAXException {
                    System.out.println("warning:"+exception);
                }        
                @Override
                public void error(SAXParseException exception) throws SAXException {
                    System.out.println("error:"+exception);
                }         
                @Override
                public void fatalError(SAXParseException exception) throws SAXException {
                    System.out.println("fatalError:"+exception);
                }
            });

            String xmlPath ="src/com/zxy97/test/xml/dom/books.xml";//XML文档路径
            Document document = builder.parse(xmlPath);//创建Document对象

            XPathFactory xpf = XPathFactory.newInstance();
            XPath xp = xpf.newXPath();
            XPathExpression xpe = xp.compile("//book[author='罗贯中' or author='施耐庵' ]/title/text()");
            Object result = xpe.evaluate(document,XPathConstants.NODESET);

            System.out.println("查询作者为罗贯中或施耐庵的图书的标题:");
            NodeList nodeList = (NodeList) result;
            for (int i = 0; i < nodeList.getLength(); i++) {
                System.out.println(nodeList.item(i));
            }
/*
run:
error:org.xml.sax.SAXParseException; systemId: file:///D:/Code/java/DesignPattern/src/com/zxy97/test/xml/dom/books.xml; lineNumber: 2; columnNumber: 8; 文档根元素 "books" 必须匹配 DOCTYPE 根 "null"。
error:org.xml.sax.SAXParseException; systemId: file:///D:/Code/java/DesignPattern/src/com/zxy97/test/xml/dom/books.xml; lineNumber: 2; columnNumber: 8; 文档无效: 找不到语法。
查询作者为罗贯中或施耐庵的图书的标题:
[#text: 三国演义]
[#text: 水浒传]
成功构建 (总时间: 0 秒)            
*/           
        } catch (ParserConfigurationException ex) {
            System.out.println("创建DocumentBuilder时发生异常:"+ex);
        } catch (SAXException | IOException ex) {
            System.out.println("创建Document时发生异常:"+ex);
        } catch (XPathExpressionException ex) {
            System.out.println("创建XPathExpression时发生异常:"+ex);
        }
    }
}

3 参考资料

《MyBatis技术内幕》

猜你喜欢

转载自blog.csdn.net/zhaoxuyang1997/article/details/82702068