XML之dom4j的xpath解析
作者:互联网
简介:
XPath 可用来在 XML 文档中对元素和属性进行遍历。
参考文档:
https://www.w3cschool.cn/xpath/xpath-syntax.html
- 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的支持:
https://dom4j.github.io/
然后是包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,xpath,dom4j,price,元素,节点,Document,XPath 来源: https://www.cnblogs.com/0099-ymsml/p/16068130.html