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 种标准轴,但开发者最常用的核心轴包括:childparentancestordescendantfollowing-sibling 等。以下是轴的通用语法结构:

轴名::节点测试[谓词]  
  • 轴名:指定导航方向(如 childparent)。
  • 节点测试:过滤节点类型(如 div@class)。
  • 谓词(可选):进一步筛选满足条件的节点。

1. 子代轴(child):向下探索的“直系子女”

子代轴是最基础的轴,它指向当前节点的直接子节点。例如,在 HTML 中,div 元素的直接子节点可能是 pspan

案例演示
假设 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.bookbodyhtml 等。

案例

<body>
  <div class="container">
    <div class="book">
      <p>作者:...</p>
    </div>
  </div>
</body>
  • XPath 表达式//p/ancestor::div
  • 含义:返回 p 节点的所有 div 祖先,包括 div.bookdiv.container

4. 后代轴(descendant):向下挖掘“所有子孙”

后代轴会定位当前节点的所有子孙节点,无论层级深度。例如,div.book 的后代可能包括 h2p、嵌套的 div 等。

案例

<div class="book">
  <h2>...</h2>
  <div class="meta">
    <p>...</p>
    <span>...</span>
  </div>
</div>
  • XPath 表达式//div[@class='book']/descendant::*
  • 含义:返回 bookdiv 下的所有后代元素。

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']
  • 含义:定位所有 classbookdiv 节点。

7. 后代或自我轴(descendant-or-self):包含自身与后代

此轴允许将当前节点视为其自身的后代,常用于模糊层级定位。例如:

  • XPath 表达式//div[descendant-or-self::p]
  • 含义:返回所有包含 p 子节点或自身是 pdiv 元素。

多轴联合查询:构建复杂路径

通过组合多个轴,可以解决更复杂的场景。例如,假设需要定位某个 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 轴是精准定位节点的核心工具,其本质是通过定义节点间的关系方向,帮助开发者构建灵活的路径表达式。掌握常用轴(如 childparentancestor)是基础,而进阶轴(如 descendant-or-selffollowing)则能应对复杂场景。

通过本文的案例与代码示例,开发者可以逐步理解轴的逻辑,并在实际项目中灵活运用。无论是网页数据抓取还是 XML 配置解析,XPath 轴(Axes) 都是提升节点定位效率的利器。建议读者通过实践不同轴的组合,进一步巩固对这一技术的理解。

最新发布