XPath怎么选择属性值以某字符串结尾的节点

用 ends-with() 函数可匹配属性值结尾,XPath 2.0+ 直接支持,如 //[ends-with(@class, 'btn')];XPath 1.0 需用 substring() 和 string-length() 模拟,如 //[substring(@class, string-length(@class)-2)='btn']。

ends-with() 函数即可,但要注意 XPath 版本支持。

XPath 2.0 及以上:直接用 ends-with()

这是最简洁的方式,适用于现代解析器(如 lxml、Saxon、XPath 2+ 的浏览器环境等):

  • //*[@class ends-with(@class, 'btn')] —— 选 class 属性以 "btn" 结尾的任意元素
  • //input[ends-with(@name, '_id')] —— 选 name 属性以 "_id" 结尾的 input 元素
  • 注意:ends-with() 区分大小写,如需忽略大小写,可组合 lower-case()//a[ends-with(lower-case(@href), '.pdf')]

XPath 1.0 兼容写法:用 substring() + string-length()

老系统(如早期 Selenium、IE、部分 DOM 解析器)只支持 XPath 1.0,没有 ends-with(),可用以下等效表达:

  • //*[@class and substring(@class, string-length(@class) - 2) = 'btn'] —— 要求 class 至少 3 字符,且最后 3 位是 "btn"
  • 通用模板(匹配以 $suffix 结尾):
    [@attr and substring(@attr, string-length(@attr) - string-length('$suffix') + 1) = '$suffix']
  • ⚠️ 注意:若属性值长度小于后缀长度,substring() 返回空字符串,条件不成立,所以天然安全,无需额外判断长度

实际使用小建议

  • 优先确认你用的解析库支持的 XPath 版本(例如 Python 的 lxml 默认支持 XPath 2.0 功能,但需启用;而原生 document.evaluate 在 Chrome 中是 XPath 1.0)
  • 如果只是简单场景,且后缀固定、长度已知,XPath 1.0 写法也够用;否则推荐升级到支持 XPath 2.0+ 的环境
  • 避免用 contains(@attr, 'xxx') 代替 —— 它匹配子串,不是“结尾”,容易误匹配(如 contains(@class, 'btn') 会命中 "button"

基本上就这些。选对版本,套对函数,就能稳稳匹配结尾属性值。