随笔都是学习笔记
随笔仅供参考,为避免笔记中可能出现的错误误导他人,请勿转载。

 

简介:

XPath 可用来在 XML 文档中对元素和属性进行遍历。

参考文档:

  • XPath 使用路径表达式在 XML 文档中进行导航
  • XPath 包含一个标准函数库
  • XPath 是 XSLT 中的主要元素
  • XPath 是一个 W3C 标准
节点:
在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。

请看下面这个 XML 文档:
 <?xml version="1.0" encoding="ISO-8859-1"?>

 <bookstore>
  <book>
     <title lang="en">Harry Potter</title>
     <author>J K. Rowling</author>
     <year>2005</year>
     <price>29.99</price>
   </book>
</bookstore> 
上面的XML文档中的节点例子:
 <bookstore> (文档节点)
 <author>J K. Rowling</author> (元素节点)
 lang="en" (属性节点) 
基本值(或称原子值,Atomic value): 基本值是无父或无子的节点。   基本值的例子:
 J K. Rowling

 "en" 
项目(Item):
项目是基本值或者节点。


节点关系:

 <bookstore>

 <book>
   <title>Harry Potter</title>
   <author>J K. Rowling</author>
   <year>2005</year>
   <price>29.99</price>
 </book>

 </bookstore> 
父(Parent)
每个元素以及属性都有一个父。
book 元素是 title、author、year 以及 price 元素的父:

子(Children):
元素节点可有零个、一个或多个子。
title、author、year 以及 price 元素都是 book 元素的子:

同胞(Sibling):
拥有相同的父的节点
title、author、year 以及 price 元素都是同胞:
先辈(Ancestor):
某节点的父、父的父,等等。
title 元素的先辈是 book 元素和 bookstore 元素:

后代(Descendant): 某个节点的子,子的子,等等。 bookstore 的后代是 book、title、author、year 以及 price 元素:

 

 

XPath 轴(Axes)

轴可定义相对于当前节点的节点集。

轴名称

结果

ancestor 选取当前节点的所有先辈(父、祖父等)。
ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。
attribute 选取当前节点的所有属性。
child 选取当前节点的所有子元素。
descendant 选取当前节点的所有后代元素(子、孙等)。
descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。
following 选取文档中当前节点的结束标签之后的所有节点。
namespace 选取当前节点的所有命名空间节点。
parent 选取当前节点的父节点。
preceding 选取文档中当前节点的开始标签之前的所有节点。
preceding-sibling 选取当前节点之前的所有同级节点。
self 选取当前节点。

 

 

XPath 运算符

下面列出了可用在 XPath 表达式中的运算符:

运算符

描述

实例

返回值

| 计算两个节点集 //book | //cd 返回所有拥有 book 和 cd 元素的节点集
+ 加法 6 + 4 10
- 减法 6 - 4 2
* 乘法 6 * 4 24
div 除法 8 div 4 2
= 等于 price=9.80

如果 price 是 9.80,则返回 true。

如果 price 是 9.90,则返回 false。

!= 不等于 price!=9.80

如果 price 是 9.90,则返回 true。

如果 price 是 9.80,则返回 false。

< 小于 price<9.80

如果 price 是 9.00,则返回 true。

如果 price 是 9.90,则返回 false。

<= 小于或等于 price<=9.80

如果 price 是 9.00,则返回 true。

如果 price 是 9.90,则返回 false。

> 大于 price>9.80

如果 price 是 9.90,则返回 true。

如果 price 是 9.80,则返回 false。

>= 大于或等于 price>=9.80

如果 price 是 9.90,则返回 true。

如果 price 是 9.70,则返回 false。

or price=9.80 or price=9.70

如果 price 是 9.80,则返回 true。

如果 price 是 9.50,则返回 false。

and price>9.00 and price<9.90

如果 price 是 9.80,则返回 true。

如果 price 是 8.50,则返回 false。

mod 计算除法的余数 5 mod 2 1

 

 

dom4j使用XPath:

默认时dom4j是不支持XPath,所以想要使用XPath就需要导入对应的jar包:

1、在dom4j网址中下载的文件中导入jaxen-1.1-beta-6.jar包,这个包是dom4j对XPath的支持:

 

 然后是包jar包导入到项目中:

详见:https://www.cnblogs.com/0099-ymsml/p/16062244.html

 

 

使用XPath:

在dom4j中提供了两个方法用来支持XPath:

NO.

方法

参数

作用

1、

获取多个节点:public List selectNodes(String xpathExpression)

xpathExpression:xpath表达式

根据 XPath 表达式将结果作为节点实例或字符串实例的列表返回。

2、

  获取一个节点:public Node selectSingleNode(String xpathExpression)  
xpathExpression:xpath表达式
 根据XPath 表达式并将结果作为单个 Node 实例返回

 

代码实现:

xml文档:

<?xml version="1.0" encoding="UTF-8"?>

<person> 
  <p1> 
    <name id="1">zs</name>  
    <age>100</age>  
    <sex>nv</sex> 
  </p1>  
  <p1> 
    <name>ls</name>  
    <age>11</age> 
  </p1> 
</person>
package XPathDemo1;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Node;
import cn.dom4jUtile.lm.Dom4jUtils;

public class XPathDemo1_1 {
    public static void main(String[] args) {
        System.out.print("selectAll: ");
        selectAll();
        System.out.print("\nselectSigle: ");
        selectSigle();
    }

    /**
     * 使用xpath获取单个标签
     */
    public static void selectSigle() {
        // 获取解析xml后的Document多像
        Document doc = Dom4jUtils.getDocument();
        // 获取对应单个节点
        Node name = doc.selectSingleNode("/person/p1/name");
        // 打印信息
        System.out.println(name.getName() + ": " + name.getText());
    }

    /**
     * 使用xpath获取所有name标签
     */
    public static void selectAll() {
        // 获取解析xml后的Document多像
        Document doc = Dom4jUtils.getDocument();
        // 通过方法selectNodes()获取对应的标签
        List<Node> name = doc.selectNodes("//name");
        // 增强for遍历列表输出信息
        for (Node node : name) {
            System.out.print("{" + node.getName() + ": " + node.getText() + "} ");
        }
    }
}

注意上面的代码有个封装类(注意修改xml文件的路径):

package cn.dom4jUtile.lm;
import java.io.File;
import java.io.FileOutputStream;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public final class Dom4jUtils {
    public static final String PATH="src" + File.separator + "XPathDemo1" + File.separator + "XPathDemo1_1.xml";
    
    /**
     * 将xml的回写操作封装为一个方法
     * @param xmlPath:xml的路径
     * @param doc:回写操作前修改数据后的Document对象
     */
    public static void ReWriteXml(Document doc) {
        try {
        //缩进文本
        OutputFormat format = OutputFormat.createPrettyPrint();
        // 创建写入流
            XMLWriter Writer = new XMLWriter(new FileOutputStream(PATH),format);
            Writer.write(doc);
            Writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 将创建解析器和解析xml的步骤封装为一个方法
     * @param path    xml文件的路径
     * @return
     */
    public static Document getDocument() {
        try {
            // 创建解析器
            SAXReader reader = new SAXReader();
            // 解析xml得到Document
            Document doc = reader.read(PATH);
            return doc; 
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}

输出结果:

 

有xml文档:

<?xml version="1.0" encoding="UTF-8"?>

<person> 
  <p1 id="1"> 
    <name>zs</name>  
    <age>100</age>  
    <sex>nv</sex> 
  </p1>  
  <p1> 
    <name>ls</name>  
    <age>11</age> 
  </p1> 
</person>
package cn.dom4jUtile.lm;
import java.io.File;
import java.io.FileOutputStream;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public final class Dom4jUtils {
    public static final String PATH="src" + File.separator + "XPathDemo1" + File.separator + "XPathDemo1_1.xml";
    
    /**
     * 将xml的回写操作封装为一个方法
     * @param xmlPath:xml的路径
     * @param doc:回写操作前修改数据后的Document对象
     */
    public static void ReWriteXml(Document doc) {
        try {
        //缩进文本
        OutputFormat format = OutputFormat.createPrettyPrint();
        // 创建写入流
            XMLWriter Writer = new XMLWriter(new FileOutputStream(PATH),format);
            Writer.write(doc);
            Writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 将创建解析器和解析xml的步骤封装为一个方法
     * @param path    xml文件的路径
     * @return
     */
    public static Document getDocument() {
        try {
            // 创建解析器
            SAXReader reader = new SAXReader();
            // 解析xml得到Document
            Document doc = reader.read(PATH);
            return doc; 
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}

上面是工具类

package XPathDemo1;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Node;
import cn.dom4jUtile.lm.Dom4jUtils;

public class XPathDemo1_1 {
    public static void main(String[] args) {
        System.out.print("selectAll: ");
        selectAll();
        System.out.println("\n");
        System.out.print("selectSigle: ");
        selectSigle();
        System.out.println("\n");
        System.out.print("<p1 id='1'>:");
        selectP1Name();
    }
    /**
     * 获取第一个p1下面name的值
     */
    public static void selectP1Name() {
        // 获取解析的doc对象
        Document doc = Dom4jUtils.getDocument();
        // 获取id="1"的p1下的name
        Node name = doc.selectSingleNode("//p1[@id='1']/name");
        // 打印信息
        System.out.print("{" + name.getName() + ": " + name.getText() + "}");
    }

    /**
     * 使用xpath获取单个标签
     */
    public static void selectSigle() {
        // 获取解析xml后的Document多像
        Document doc = Dom4jUtils.getDocument();
        // 获取对应单个节点
        Node name = doc.selectSingleNode("/person/p1/name");
        // 打印信息
        System.out.print("{" + name.getName() + ": " + name.getText() + "} ");
    }

    /**
     * 使用xpath获取所有name标签
     */
    public static void selectAll() {
        // 获取解析xml后的Document多像
        Document doc = Dom4jUtils.getDocument();
        // 通过方法selectNodes()获取对应的标签
        List<Node> name = doc.selectNodes("//name");
        // 增强for遍历列表输出信息
        for (Node node : name) {
            System.out.print("{" + node.getName() + ": " + node.getText() + "} ");
        }
    }
}

输出结果:

 

posted on 2022-03-28 17:19  时间完全不够用啊  阅读(629)  评论(0编辑  收藏  举报