XPath 概述
本章定位 :理解 XPath 在 XML 技术栈中的位置——它是 XML 的"查询语言",是 XSLT、XQuery 和 Schema 验证的基础。掌握 XPath 的七种节点类型和数据模型。
定义与作用
XPath (XML Path Language)是一种在 XML 文档中 定位节点 的表达语言。如果 XML 文档是一棵树,XPath 就是在这棵树上走路的地图坐标。
XPath 是 XSLT 和 XQuery 的底层基础:
- XSLT 用 XPath 选择要转换的节点
- XQuery 用 XPath 定位要查询的数据
- XSD 用 XPath 的受限形式(XPath 2.0 子集)实现 identity constraints
XPath 本身不操作节点,只返回节点集的 引用——具体操作由上层语言(XSLT/XQuery/DOM API)完成。
核心原理:XPath 在 XML 技术栈的位置
图解释 :XPath 是 XML 技术栈的中间层。它不操作数据,只负责"找到"——找到后,XSLT 负责转换、XQuery 负责查询、DOM API 负责修改。这种关注点分离使每个工具职责单一。
语法/结构要点
XPath 七种节点类型
| 节点类型 | 示例 | XPath 中如何选择 |
|---|---|---|
| 文档节点(根节点) | / | / |
| 元素节点 | <book> | book 或 /bookstore/book |
| 属性节点 | category="web" | @category |
| 文本节点 | Learning XML | text() |
| 注释节点 | <!-- comment --> | comment() |
| 处理指令节点 | <?xml-stylesheet?> | processing-instruction() |
| 命名空间节点 | xmlns:xsl="..." | namespace::*(已弃用) |
路径表达式 vs 文件系统路径
| 文件系统 | XPath | 含义 |
|---|---|---|
/ | /bookstore | 从根开始 |
./ | book | 从当前位置 |
../ | ../book | 上一级 |
| — | //book | 任意位置(特有) |
完整示例:小崔用 XPath 快速排查 XML 数据
场景说明
飞翔科技的后端 小崔 面对一个 5000 行的学生数据 XML,需要快速找出"所有计算机科学专业的、成绩为 A+ 的学生"。如果用 DOM 遍历写代码需要几十行,用 XPath 一行搞定。
XML 数据
<?xml version="1.0" encoding="UTF-8"?>
<university>
<student id="S001" major="计算机科学">
<name>小崔</name>
<courses>
<course code="CS301" grade="A+">XML技术</course>
<course code="CS402" grade="B+">Java高级</course>
</courses>
</student>
<student id="S002" major="软件工程">
<name>黄俪</name>
<courses>
<course code="CS301" grade="A+">XML技术</course>
</courses>
</student>
<student id="S003" major="计算机科学">
<name>白歌</name>
<courses>
<course code="CS402" grade="A">Java高级</course>
</courses>
</student>
</university>
用 XPath 查询
from lxml import etree
tree = etree.parse("students.xml")
# 查询1:所有计算机科学专业的学生姓名
names = tree.xpath("//student[@major='计算机科学']/name/text()")
print(f"计算机科学专业学生: {names}")
# → ['小崔', '白歌']
# 查询2:所有成绩为 A+ 的课程
aplus = tree.xpath("//course[@grade='A+']/text()")
print(f"成绩 A+ 的课程: {aplus}")
# → ['XML技术', 'XML技术']
# 查询3:同时满足两个条件
result = tree.xpath(
"//student[@major='计算机科学']/courses/course[@grade='A+']/text()"
)
print(f"计算机科学 A+ 课程: {result}")
# → ['XML技术']
操作结果
查询 3 只返回了"小崔的 XML 技术"——因为白歌虽然是计算机科学专业,但没有 A+ 成绩。XPath 一行表达式完成了原本需要嵌套循环+条件判断的逻辑。
易错场景
错误一:混淆根节点(/)和根元素
/是文档根节点(document node),它是所有内容的父节点/bookstore是根元素(root element),它是 XML 文档最外层的元素/bookstore/book选择 bookstore 的直接子 book 元素//book选择文档中任意位置的 book 元素
错误二:文本节点含空白
<name>
小崔
</name>
//name/text() 返回的是 "\n 小崔\n"(含换行和缩进空白),需要用 normalize-space() 函数去除。
面试考点
| 考点 | 参考答案要点 |
|---|---|
| XPath 是什么?在 XML 技术栈中扮演什么角色? | 节点定位语言,是 XSLT 和 XQuery 的基础。负责在 DOM 树中选择节点集,不修改数据 |
| XPath 有哪七种节点类型? | 文档(根)、元素、属性、文本、注释、处理指令、命名空间。最常用的是元素和属性节点 |
XPath 中 / 和 // 的区别? | / 从根节点选择直接子级;// 从当前上下文或文档中任意深度选择匹配节点(等价 descendant-or-self::node()/) |