Skip to content

XPath 路径表达式

XPath 是一种用于在 XML/HTML 文档中定位节点的语言。Legado 源支持使用 XPath 规则提取网页内容,以 // 开头的规则会自动识别为 XPath 表达式。

注:本文所有代码均通过 Chrome(版本 123.0.6312.86) 验证

1. 轴 (Axes)

XPath 规范定义了 13 种轴,用于定位元素树上相对于当前元素的节点。

说明缩写
attribute元素的属性@
self元素本身.
parent当前元素的父元素..
child当前元素的子元素
ancestor当前元素的所有直属祖先
ancestor-or-self当前元素及其所有直属祖先
descendant当前元素的所有递归子元素
descendant-or-self当前元素及其所有递归子元素
following当前元素之后出现的所有元素(无视层级,不含直属后代)
following-sibling当前元素之后出现的所有同级元素
preceding当前元素之前出现的所有元素(无视层级,不含直属祖先)
preceding-sibling当前元素之前出现的所有同级元素
namespace不支持

语法轴名::表达式

js
> $x('//body/ancestor-or-self::*')
< [body, html]

2. 路径格式

XPath 通过"路径表达式"(Path Expression)选取元素,形式上与文件系统路径类似。

概念说明
/路径内部分隔符
绝对路径/ 起首,后跟根元素,如 /step/step/...
相对路径除绝对路径外的其他写法,如 step/step
.当前元素
..当前元素的父元素

选取语法

符号说明
/选取根元素
//选取任意位置的某个元素
nodename选取指定名称的元素
@选取某个属性

3. 示例

以下示例基于这段 HTML:

html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>标题</title>
        <meta property="author" content="作者" />
    </head>
    <body>
        <div>
            <title lang="eng">Harry Potter</title>
            <p>29.39</p>
            <p>usd</p>
        </div>
        <div>
            <title lang="cn">Cpp高级编程</title>
            <p>39.95</p>
            <p>rmb</p>
        </div>
        <div id="list">
            <dl>
                <dd><a href="/1">一</a></dd>
                <dd><a href="/2">二</a></dd>
                <dd><a href="/3">三</a></dd>
            </dl>
        </div>
    </body>
</html>
表达式结果说明
$x('/')[document]选取根元素
$x('/html')[html]绝对路径选取
$x('html/head/meta')[meta, meta]相对路径选取
$x('//p')[p, p, p, p]选取所有 p 元素
$x('html/body//a')[a, a, a]选取 body 下所有 a
$x('//@lang')[lang, lang]选取属性
$x('//meta/..')[head]选取父元素

4. 谓语条件 (Predicate)

谓语条件是对路径表达式的附加筛选条件,写在方括号 [] 中。

表达式结果说明
html/head/meta[1]<meta charset="utf-8">选取第一个
html/head/meta[last()]<meta property="author" ...>选取最后一个
html/head/meta[last()-1]<meta charset="utf-8">选取倒数第二个
html/head/meta[position()>1]<meta property="author" ...>位置大于 1
//title[@lang]两个 title具有特定属性
//title[@lang="eng"]English title属性值匹配
/html/body/div[dl]<div id="list">包含特定子元素
/html/body/div[p>35.00]Cpp 高级编程 div子元素值条件

5. 通配符

符号说明
*匹配任何元素
@*匹配任何属性名
js
$x('//*')          // 选取所有元素
$x('/*/*')         // 选取所有第二层元素
$x('//title[@*]')  // 选取所有带属性的 title

6. 多路径选择

| 合并多个表达式的选取结果:

js
$x('//title | //a')  // 选取所有 title 和 a 元素

7. 函数

XPath 函数的参数可以是静态字符串或表达式,函数可嵌套调用。XPath 索引从 1 开始。

函数说明示例
boolean()转换为布尔值boolean(//title)true
number()转换为数字number(//p[1])29.39
round()四舍五入round(//p[1])29
ceiling()向上取整ceiling(//p[1])30
floor()向下取整floor(//p[1])29
concat()字符串拼接concat("cost:", //p[1], //p[2])'cost:29.39usd'
contains()判断是否包含contains(//p[1], "29.39")true
count()统计元素个数count(//p)4
id()根据 id 选取id("list")[dl#list]
last()同级元素集合数量//p[last()]
name()返回元素名name(//*[@id])'dl'
normalize-space()去除前后空白normalize-space(" test ")'test'
not()返回布尔反值//title[not(@lang)]
position()返回元素位置//meta[position()=2]
starts-with()检查字符串开头//title[starts-with(., "Cpp")]
string()转换为字符串string(//p)'29.39'
string-length()返回字符串长度string-length(string(//p))5
substring()截取字符串substring(string(//p), 1, 3)'29.'
substring-after()某字符之后的字符串substring-after(string(//p), ".")'39'
substring-before()某字符之前的字符串substring-before(string(//p), ".")'29'
sum()对数字求和sum(//p[1])69.34
translate()依次替换字符translate("aabbcc", "ac", "V8")'VVbb88'

基于 Apache-2.0 许可发布