XPath的|运算符是用于合并多个路径表达式返回结果集的特殊运算符,它可以把两个或多个独立XPath查询得到的节点集合并成一个统一的节点集,且合并后的结果集会自动去重,不会包含重复的节点。

|运算符的基本语法
|运算符的使用方式非常简单,只需要在多个XPath路径表达式之间用|连接即可,语法格式如下:
<!-- 基础语法格式 --> 路径表达式1 | 路径表达式2 | 路径表达式3
执行时会先分别计算每个路径表达式对应的结果集,再将所有结果集的元素合并,最终返回合并后的节点集合。
结果集合并的核心规则
使用|运算符合并结果集时,遵循以下两个核心规则:
- 合并后的节点集包含所有参与合并的结果集中的节点,不会遗漏任何一个结果集的元素。
- 合并过程会自动去重,如果多个结果集包含同一个节点,最终合并结果中只会保留该节点一次,不会重复出现。
实际使用示例
XML文档解析场景
假设我们有如下结构的XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="编程">
<title>Python基础教程</title>
<author>张三</author>
<price>59.9</price>
</book>
<book category="文学">
<title>散文精选</title>
<author>李四</author>
<price>39.9</price>
</book>
<magazine>
<name>科技周刊</name>
<issue>2024年第10期</issue>
</magazine>
</bookstore>
如果我们想要同时获取所有<book>节点的<title>和所有<magazine>节点的<name>,就可以使用|运算符:
//book/title | //magazine/name
该表达式会返回两个<title>节点和一个<name>节点,合并后的结果集包含三个节点,没有重复元素。
HTML文档解析场景
在HTML解析中,|运算符同样适用,比如我们要提取页面中所有的<h1>标题和<h2>标题,对应的XPath表达式为:
//h1 | //h2
如果页面中同时存在h1和h2标签,该表达式会返回所有匹配的h1和h2节点,且如果某个节点同时被两个路径匹配(比如某个节点既是h1又是h2,这种情况极少出现),也只会保留一次。
注意事项
使用|运算符时需要注意以下几点:
- |运算符两侧的路径表达式可以是任意合法的XPath表达式,不要求路径有层级关联。
- 合并的结果集的节点顺序按照文档中的原始顺序排列,不是按照路径表达式的先后顺序。
- 如果某个路径表达式没有匹配到任何节点,不会影响其他路径表达式的结果,最终合并结果只包含有匹配结果的节点。
代码示例演示
以下是使用Python的lxml库演示|运算符合并结果集的完整代码:
from lxml import etree
# 定义XML内容
xml_content = """<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="编程">
<title>Python基础教程</title>
<author>张三</author>
<price>59.9</price>
</book>
<book category="文学">
<title>散文精选</title>
<author>李四</author>
<price>39.9</price>
</book>
<magazine>
<name>科技周刊</name>
<issue>2024年第10期</issue>
</magazine>
</bookstore>"""
# 解析XML
tree = etree.XML(xml_content.encode("utf-8"))
# 使用|运算符合并结果集
xpath_expr = "//book/title | //magazine/name"
result_nodes = tree.xpath(xpath_expr)
# 输出结果
print("合并后的结果集节点内容:")
for node in result_nodes:
print(node.text)
运行上述代码,会输出以下内容:
合并后的结果集节点内容: Python基础教程 散文精选 科技周刊
可以看到三个节点都被正确合并到结果集中,且没有重复内容。