XPath的last()函数是用于获取当前上下文节点集合中最后一个节点索引的内置函数,在XML、HTML文档的节点定位场景中应用十分广泛,很多开发者在编写定位规则时都需要用到它来处理末尾节点的提取需求。

last()函数的基础作用
last()函数的核心作用是返回当前上下文节点集合的总长度,也就是集合中最后一个节点的位置索引。需要注意的是,XPath中节点的位置索引是从1开始计数的,这和很多编程语言中从0开始计数的逻辑不同。
比如在一个包含5个<li>节点的<ul>列表中,当前上下文节点集合就是这5个<li>节点,此时调用last()函数会返回数值5,表示集合总共有5个节点,最后一个节点的索引是5。
last()函数的常见用法
1. 单独提取最后一个节点
如果只需要获取某个父节点下的最后一个子节点,可以直接将last()函数作为谓语条件使用。比如要提取下面HTML结构中最后一个<li>元素:
<ul class="list"> <li>第一个项目</li> <li>第二个项目</li> <li>第三个项目</li> <li>第四个项目</li> </ul>
对应的XPath表达式为:
//ul[@class="list"]/li[last()]
这个表达式会先定位到class为list的ul节点,再获取它下面的所有li子节点,最后通过last()筛选出最后一个li节点,也就是内容为第四个项目的节点。
2. 结合偏移量提取倒数第N个节点
如果需要提取倒数第N个节点,可以用last()减去对应的偏移量。比如要提取上面示例中倒数第二个<li>节点,XPath表达式可以写成:
//ul[@class="list"]/li[last()-1]
这里last()返回4,减去1之后得到3,所以会匹配索引为3的第三个<li>节点,内容为第三个项目。
3. 在嵌套节点中使用last()
当文档结构存在嵌套时,last()函数的作用范围是当前上下文的节点集合,不会受到外层节点的影响。比如下面的嵌套结构:
<div class="container">
<div class="group">
<p>第一组第一段</p>
<p>第一组第二段</p>
</div>
<div class="group">
<p>第二组第一段</p>
<p>第二组第二段</p>
<p>第二组第三段</p>
</div>
</div>
如果要获取每个class为group的div下的最后一个<p>节点,XPath表达式可以写成:
//div[@class="group"]/p[last()]
这个表达式会分别匹配两个group节点下的最后一个p节点,结果分别是第一组第二段和第二组第三段,last()在每个group的p节点集合内独立计算。
使用last()函数的注意事项
- last()函数的索引从1开始,不要和编程语言的0基索引混淆,避免出现定位偏差。
- last()函数只能用在谓语中,不能直接作为节点名使用,比如
//li[last()]是合法的,//last()是不合法的。 - 如果当前上下文节点集合为空,last()函数会返回0,此时使用
li[last()]不会匹配到任何节点。
代码示例:用Python验证last()函数效果
可以通过Python的lxml库实际运行XPath表达式,验证last()函数的作用,示例代码如下:
from lxml import etree
# 定义测试HTML内容
html_content = """
<ul class="test-list">
<li>节点1</li>
<li>节点2</li>
<li>节点3</li>
</ul>
"""
# 解析HTML
tree = etree.HTML(html_content)
# 测试last()提取最后一个节点
last_node = tree.xpath('//ul[@class="test-list"]/li[last()]/text()')
print("最后一个节点内容:", last_node) # 输出: ['节点3']
# 测试last()-1提取倒数第二个节点
second_last_node = tree.xpath('//ul[@class="test-list"]/li[last()-1]/text()')
print("倒数第二个节点内容:", second_last_node) # 输出: ['节点2']
运行上面的代码可以直观看到last()函数的实际返回效果,帮助理解它的使用逻辑。