XPath 轴(Axes)(建议收藏)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
在网页数据抓取、XML文档解析或自动化测试等场景中,XPath 是一种不可或缺的工具。它通过灵活的语法路径表达式,帮助开发者精准定位目标节点。然而,许多开发者在学习 XPath 时,容易被其复杂的轴(Axes)概念所困扰。本文将系统性地解析 XPath 轴(Axes) 的核心原理,结合形象比喻与实战案例,帮助编程初学者和中级开发者快速掌握这一技术。
什么是 XPath 轴?
XPath 轴可以理解为一种导航规则,它定义了节点间的关系方向。想象你站在一棵家族树的某个节点上,轴就是指引你向不同方向探索其他节点的“路线图”。例如:
- 父轴(parent):指向你的父亲节点;
- 子代轴(child):指向你所有的孩子节点;
- 后代轴(descendant):指向你所有子孙节点(包括孙子、曾孙等)。
每个轴都对应一种特定的节点间关系,通过组合不同轴,可以构建复杂的路径表达式,从而精准定位目标节点。
XPath 轴的分类与基本语法
XPath 定义了 13 种标准轴,但开发者最常用的核心轴包括:child
、parent
、ancestor
、descendant
、following-sibling
等。以下是轴的通用语法结构:
轴名::节点测试[谓词]
- 轴名:指定导航方向(如
child
、parent
)。 - 节点测试:过滤节点类型(如
div
、@class
)。 - 谓词(可选):进一步筛选满足条件的节点。
1. 子代轴(child):向下探索的“直系子女”
子代轴是最基础的轴,它指向当前节点的直接子节点。例如,在 HTML 中,div
元素的直接子节点可能是 p
或 span
。
案例演示:
假设 HTML 结构如下:
<div class="book">
<h2>《算法导论》</h2>
<p>作者:Thomas H. Cormen</p>
<div class="price">¥129.00</div>
</div>
- XPath 表达式:
child::div[@class='book']/child::p
- 含义:定位到
book
类的div
元素,再找到它的直接子节点p
。
代码示例(Python):
from lxml import etree
html = """
<div class="book">
<h2>《算法导论》</h2>
<p>作者:Thomas H. Cormen</p>
<div class="price">¥129.00</div>
</div>
"""
root = etree.HTML(html)
result = root.xpath("//div[@class='book']/child::p/text()")
print(result) # 输出:['作者:Thomas H. Cormen']
2. 父轴(parent):向上追溯的“直接长辈”
父轴用于定位当前节点的直接父节点。例如,若当前节点是 p
标签,则父轴会指向其父级 div
。
案例:
继续使用上例的 HTML 结构:
- XPath 表达式:
//p/parent::div
- 含义:定位到所有
p
节点的父级div
。
代码示例:
parent_div = root.xpath("//p/parent::div/@class")
print(parent_div) # 输出:['book']
3. 祖先轴(ancestor):追溯到“所有长辈”
祖先轴会返回从当前节点到根节点路径上的所有祖先节点。例如,若当前节点是 p
,则其祖先可能包括 div.book
、body
、html
等。
案例:
<body>
<div class="container">
<div class="book">
<p>作者:...</p>
</div>
</div>
</body>
- XPath 表达式:
//p/ancestor::div
- 含义:返回
p
节点的所有div
祖先,包括div.book
和div.container
。
4. 后代轴(descendant):向下挖掘“所有子孙”
后代轴会定位当前节点的所有子孙节点,无论层级深度。例如,div.book
的后代可能包括 h2
、p
、嵌套的 div
等。
案例:
<div class="book">
<h2>...</h2>
<div class="meta">
<p>...</p>
<span>...</span>
</div>
</div>
- XPath 表达式:
//div[@class='book']/descendant::*
- 含义:返回
book
类div
下的所有后代元素。
5. 兄弟轴(following-sibling 和 preceding-sibling):横向探索“同辈节点”
- following-sibling:定位当前节点之后的兄弟节点;
- preceding-sibling:定位当前节点之前的兄弟节点。
案例:
<div class="books">
<div class="book">《算法导论》</div>
<div class="book">《设计模式》</div>
<div class="book">《重构》</div>
</div>
- XPath 表达式:
//div[@class='book'][1]/following-sibling::div
- 含义:返回第一个
book
节点之后的所有div
兄弟节点(即《设计模式》和《重构》)。
进阶轴与复杂场景应用
6. 自我轴(self):聚焦“自身节点”
self
轴用于明确指定当前节点本身。例如:
- XPath 表达式:
//div[self::div and @class='book']
- 含义:定位所有
class
为book
的div
节点。
7. 后代或自我轴(descendant-or-self):包含自身与后代
此轴允许将当前节点视为其自身的后代,常用于模糊层级定位。例如:
- XPath 表达式:
//div[descendant-or-self::p]
- 含义:返回所有包含
p
子节点或自身是p
的div
元素。
多轴联合查询:构建复杂路径
通过组合多个轴,可以解决更复杂的场景。例如,假设需要定位某个 div
元素之后的所有 span
节点:
//div[@id='target']/following::span
实战案例:
<div id="target">起点</div>
<p>无关内容</p>
<span>第一个目标节点</span>
<span>第二个目标节点</span>
- XPath 表达式:
//div[@id='target']/following::span
- 结果:返回两个
span
节点。
总结
XPath 轴是精准定位节点的核心工具,其本质是通过定义节点间的关系方向,帮助开发者构建灵活的路径表达式。掌握常用轴(如 child
、parent
、ancestor
)是基础,而进阶轴(如 descendant-or-self
、following
)则能应对复杂场景。
通过本文的案例与代码示例,开发者可以逐步理解轴的逻辑,并在实际项目中灵活运用。无论是网页数据抓取还是 XML 配置解析,XPath 轴(Axes) 都是提升节点定位效率的利器。建议读者通过实践不同轴的组合,进一步巩固对这一技术的理解。