XPath JAVA用法总结以及代码样例

基本概念介绍

XPath 是一门在 XML 文档中查找信息的语言, 可用来在 XML 文档中对元素和属性进行遍历。XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 同时被构建于 XPath 表达之上。因此,对 XPath 的理解是很多高级 XML 应用的基础。

XPath非常类似对数据库操作的SQL语言,或者说JQuery,它可以方便开发者抓起文档中需要的东西。(dom4j也支持xpath。

节点类型

XPath中有七种结点类型:元素、属性、文本、命名空间、处理指令、注释以及文档节点(或称为根节点)。文档中存在元素节点,属性节点,根节点

常用路径表达式

表达式 描述
节点名称(nodename) 选取此节点的所有子节点
/ 从根节点选取
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性

示例如下
//@lang 选取所有名为 lang 的属性

限定语

用来查找某个特定的节点或者包含某个指定的值的节点。以方括号括起

表达式 描述
//book[price>35.00] 选择所有book 元素,且其中的 price 元素的值须大于 35.00
/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
/bookstore/book[price>35.00] 选取所有 bookstore 元素的 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title 选取所有 bookstore 元素中的 book 元素的 title 元素,且其中的 price 元素的值须大于 35.00。

通配符

表达式 描述
* 匹配任何元素节点
@* 匹配任何属性节点
node() 匹配任何类型的节点
| 选取若干路径

示例

路径表达式 结果
/bookstore/* 选取 bookstore 元素的所有子节点
//* 选取文档中的所有元素
//title[@*] 选取所有带有属性的 title 元素。
//book/title | //book/price 选取所有 book 元素的 tilte 和 price 元素。
//title | //price 选取所有文档中的 title 和 price 元素。
/bookstore/book/title | //price 选取所有属于 bookstore 元素的 book 元素的 title 元素,以及文档中所有的 price 元素

XPath API

XPathFactory类

XPathFactory实例可用于创建XPath对象。该类只有一个受保护的空构造方法,
常用的方法是:

static XPathFactory newInstance( ):获取使用默认对象模型(DOM)的新XPathFactory 实例。

XPath 接口

提供了对XPath计算环境和表达式的访问。XPath对象不是线程安全的,也不能重复载入。也就是说应用程序负责确保在任意给定时间内不能有多个线程使用一个XPath对象。
常用方法:

XPathExpression compile(String expression):编译XPath表达式。 

XPath.evaluate()

  • XPath.evaluate(String expression, InputSource source, QName returnType) :计算指定 InputSource 上下文中的 XPath 表达式并返回指定类型的结果。
  • XPath.evaluate(String expression, Object item, QName returnType) : 计算指定上下文中的 XPath 表达式并返回指定类型的结果。其中第三个参数就是用于指定需要的返回类型,该参数的值都是在XPathConstants中已经命名的静态字段。如下:
XPathConstants.BOOLEAN 
XPathConstants.NODESET 
XPathConstants.NUMBER 
XPathConstants.STRING 
XPathConstants.STRING
XPathConstants.NODE

注:XPathConstants.NODE它主要适用于当XPath表达式的结果有且只有一个节点。如果XPath表达式返回了多个节点,却指定类型为XPathConstants.NODE,则evaluate()方法将按照文档顺序返回第一个节点。如果XPath表达式的结果为一个空集,却指定类型为XPathConstants.NODE,则evaluate( )方法将返回null。

代码示例

package test.mybatis.xml;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import test.mybatis.ResourceLoader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

/**
 * Created on 2016/12/6 0006.
 *
 * @author zlf
 * @since 1.0
 */
public class XpathDemo {
    private static Document document;
    private static XPath xPath;

    public static void main(String[] args) throws Exception {
        init();
        getRootEle();
        getChildEles();
        getPartEles();
        haveChildsEles();
        getAttrEles();

        //打印根节点下的所有元素节点
        System.out.println(document.getDocumentElement().getChildNodes().getLength());
        NodeList nodeList = document.getDocumentElement().getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
                System.out.print(nodeList.item(i).getNodeName() + " ");
            }
        }
    }

    //初始化Document,XPath对象
    public static void init() throws Exception {
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        builderFactory.setValidating(false);
        DocumentBuilder builder = builderFactory.newDocumentBuilder();
        document = builder.parse(ResourceLoader.class.getClassLoader().getResourceAsStream("test/mybatis/book.xml"));

        //创建XPath对象
        XPathFactory factory = XPathFactory.newInstance();
        xPath = factory.newXPath();
    }

    //获取根元素
    //表达式可以更换为/* /book
    public static void getRootEle() throws Exception {
//        Node node = (Node) xPath.evaluate("/book", document, XPathConstants.NODE);
        Node node = (Node) xPath.evaluate("/*", document, XPathConstants.NODE);
        System.out.println(node.getNodeName() + "---------------" + node.getNodeValue());
    }

    //获取子元素并打印
    public static void getChildEles() throws Exception {
        NodeList nodeList = (NodeList) xPath.evaluate("book/authors/author", document, XPathConstants.NODESET);
        for (int i = 0; i < nodeList.getLength(); i++) {
            System.out.println(nodeList.item(i).getNodeName() + " ");
        }
        System.out.println();
    }

    //获取部分元素
    //获取元素名称为author的元素
    public static void getPartEles() throws Exception {
        NodeList nodeList = (NodeList) xPath.evaluate("//*[name() = 'price']", document, XPathConstants.NODESET);
        for (int i = 0; i < nodeList.getLength(); i++) {
            System.out.print(nodeList.item(i).getNodeName() + "-->"
                    + nodeList.item(i).getTextContent());
        }
        System.out.println();
    }

    // 获取包含子节点的元素
    public static void haveChildsEles() throws Exception {
        NodeList nodeList = (NodeList) xPath.evaluate("//*[*]", document, XPathConstants.NODESET);
        for (int i = 0; i < nodeList.getLength(); i++) {
            System.out.print(nodeList.item(i).getNodeName() + " ");
        }
        System.out.println();
    }

    // 获取指定属性的元素
    // 获取所有年龄大于35的人员名称
    public static void getAttrEles() throws Exception {
        NodeList nodeList = (NodeList) xPath.evaluate("//authors/author[@age>35]/@name", document, XPathConstants.NODESET);
        for (int i = 0; i < nodeList.getLength(); i++) {
            System.out.print(nodeList.item(i).getNodeName() + "-->"
                    + nodeList.item(i).getTextContent() + " ");
        }
        System.out.println();
    }
}

package test.mybatis.xml;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import test.mybatis.ResourceLoader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

/**
 * Created on 2016/11/29 0029.
 *
 * @author zlf
 * @since 1.0
 */

/*      <?xml version="1.0" encoding="UTF-8"?>
        <book>
        <bookname name="XML详解" font="GB2312"></bookname>
        <authors>
        <author name="张孝祥" sex="男" age="45"></author>
        <author name="王勇" sex="男" age="35"></author>
        <author name="王波" sex="男" age="30"></author>
        </authors>
        <price value="¥55"></price>
        <publishdate>
        <value>2009-08-18</value>
        </publishdate>
        </book>
 */
public class XPathForXml {
    public static void main(String[] args) {
        new XPathForXml().parseXMLWithJdk();
    }

    public void parseXMLWithJdk() {
        try {
            //读取book.xml到内存
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse(ResourceLoader.class.getClassLoader().getResourceAsStream("test/mybatis/book.xml"));
//            Document document = builder.parse(new FileInputStream("G:\\projects\\mybatistest\\src\\main\\resources\\test\\mybatis\\book.xml"));
            //通过xml获得book的authors的authors的author子节点
            XPathFactory xPathFactory = XPathFactory.newInstance();
            XPath xPath = xPathFactory.newXPath();
            NodeList authors = (NodeList) xPath.evaluate("book/authors/author", document, XPathConstants.NODESET);
            System.out.println(authors.getLength());
            String name = "";
            String sex = "";
            String age = "";
            //遍历元素
            if (authors != null) {
                for (int i = 0; i < authors.getLength(); i++) {
                    Node author = authors.item(i);
                    int n = i + 1;
                    name = (String) xPath.evaluate("@name", author, XPathConstants.STRING);
                    sex = (String) xPath.evaluate("@sex", author, XPathConstants.STRING);
                    age = (String) xPath.evaluate("@age", author, XPathConstants.STRING);
                    System.out.println(n + ". 名字:" + name+",性别:"+sex+",年龄:"+age);
                }
            }
            //获得book的authors的第一个子节点,注意NODESET和NODE的区别
            Node author = (Node) xPath.evaluate("book/authors/author", document, XPathConstants.NODE);
            System.out.println("名称:" + author.getNodeName());
            System.out.println("内容:" + author.getTextContent());//如果存在内容则返回内容,不存在则返回空

            //获取节点的属性
            NamedNodeMap namedNodeMap = author.getAttributes();
            System.out.println("该节点的属性个数:" + namedNodeMap.getLength());

            //遍历元素的属性
            if (namedNodeMap != null) {
                for (int i = 0; i < namedNodeMap.getLength(); i++) {
                    int n = i + 1;
                    System.out.print("属性" + n + "名称" + namedNodeMap.item(i).getNodeName()+" ");
                    System.out.print("值" + namedNodeMap.item(i).getNodeValue()+" ");
                    System.out.print("类型" + namedNodeMap.item(i).getNodeType()+" ");
                    System.out.println();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

github地址:

{% github longfeizheng mybatisDemo 678cf11 %}

参考:
https://my.oschina.net/cloudcoder/blog/223359
http://blog.csdn.net/lululove19870526/article/details/53116062

共有 0 条评论

 Top