XPath的substring()函数是用于从字符串中提取指定子串的内置函数,它可以根据起始位置和长度参数,精准截取目标字符串的对应部分,在XML、HTML文档解析场景中使用频率很高。

substring()函数的基本语法
substring()函数的标准语法格式如下:
<!-- 语法格式 --> substring(源字符串, 起始位置, 截取长度)
三个参数的具体含义如下:
- 源字符串:需要提取子串的原始字符串,可以是直接的字符串字面量,也可以是返回字符串的XPath表达式,比如节点文本内容。
- 起始位置:截取子串的开始位置,XPath中字符串的索引从1开始,不是从0开始。
- 截取长度:可选参数,指定需要截取的字符数量,如果不传这个参数,会截取从起始位置到源字符串末尾的所有内容。
基础使用示例
提取固定长度的子串
假设我们有一个XML文档,其中<user>节点的text内容是张三_2024001,我们需要提取前面的用户姓名,也就是前两个字符:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<user>张三_2024001</user>
</root>
对应的XPath表达式如下:
<!-- 提取user节点内容的前2个字符 --> substring(/root/user/text(), 1, 2)
执行这个表达式后,返回的结果是张三。
截取从指定位置到末尾的内容
还是以上面的XML为例,如果我们需要提取下划线后面的用户编号,也就是从第3个字符开始到末尾的内容:
<!-- 从第3个字符开始截取到末尾 --> substring(/root/user/text(), 3)
执行后返回的结果是_2024001。
结合其他XPath函数使用
substring()函数经常会和string-length()、contains()等函数配合使用,处理更复杂的提取需求。
提取最后N个字符
如果我们想提取字符串的最后3个字符,可以先计算字符串总长度,再计算起始位置:
<!-- 提取user节点内容的最后3个字符 --> substring(/root/user/text(), string-length(/root/user/text()) - 2, 3)
上面的表达式中,string-length()用来获取源字符串的总长度,减去2之后得到倒数第3个字符的位置,再截取3个字符,最终返回001。
根据分隔符提取内容
当字符串中包含固定的分隔符时,可以结合contains()和string-length()实现动态提取:
<!-- 提取分隔符_之前的内容 --> substring(/root/user/text(), 1, string-length(/root/user/text()) - string-length(substring-after(/root/user/text(), '_')))
这里substring-after()函数会返回分隔符_后面的内容,用总长度减去这部分的长度,就得到了分隔符前面内容的长度,再用substring()截取即可,返回结果是张三。
使用注意事项
- 起始位置如果小于1,会按照1来计算,比如
substring('abc', 0, 2)的结果是ab。 - 如果起始位置大于源字符串的长度,函数会返回空字符串。
- 如果截取长度小于等于0,也会返回空字符串。
- 如果起始位置加截取长度超过了源字符串的长度,会截取从起始位置到末尾的所有内容,不会报错。
不同解析库中的使用差异
大部分支持XPath 1.0的解析库都支持substring()函数,比如Python的lxml库、Java的JDOM库等,使用方式基本一致。下面是Python lxml库的使用示例:
from lxml import etree
# 构造XML文档
xml_content = """<?xml version="1.0" encoding="UTF-8"?>
<root>
<user>张三_2024001</user>
</root>"""
# 解析文档
tree = etree.fromstring(xml_content.encode('utf-8'))
# 执行XPath提取
result = tree.xpath('substring(/root/user/text(), 1, 2)')
print(result) # 输出:张三
需要注意的是,XPath 2.0及以上版本还提供了substring-before()、substring-after()等更便捷的截取函数,如果是使用支持高版本XPath的解析库,也可以根据需求选择对应的函数。
XPathsubstring_functionXML解析子字符串提取修改时间:2026-06-10 06:30:26