如何用XPath仅在子元素含title属性时提取父元素目标文本
解决方案:精准提取符合条件的父元素文本
当然可行!我来帮你构建满足需求的XPath查询,完美匹配你要的场景。
核心思路
我们需要完成两个关键步骤:
- 筛选符合条件的
<li>元素:仅当它的后代<i>/<a>存在title属性时才选中它; - 提取
<li>的独立文本:排除子元素(比如<a>里的"Apples")的文本,只取<li>自身的文本内容。
分步实现
1. 先定位符合条件的<li>
用这个XPath片段筛选出满足要求的<li>:
//ul/li[./i/a/@title]
这个表达式的意思是:选择所有<ul>下的<li>,且该<li>下存在<i>/<a>元素,并且<a>带有title属性。
2. 提取<li>的自身文本(不含子元素文本)
在上面的基础上,我们需要获取<li>的直接文本节点,过滤掉空的空格节点,然后提取有效内容:
//ul/li[./i/a/@title]/text()[normalize-space()][last()]
text():获取<li>的所有直接文本节点(示例里包括换行空格和(1999));[normalize-space()]:过滤掉纯空格的无效文本节点;[last()]:取最后一个有效文本节点,也就是示例里的(1999)。
3. 直接提取1999(去掉括号)
如果需要直接得到不带括号的1999,可以根据XPath版本选择不同的方式:
- XPath 2.0+(支持正则替换):
replace(normalize-space(//ul/li[./i/a/@title]/text()[normalize-space()][last()]), '[()]', '') - XPath 1.0(无正则,用字符串截取):
substring(normalize-space(//ul/li[./i/a/@title]/text()[normalize-space()][last()]), 2, 4)
为什么你之前的尝试不生效?
//ul/li/text()[last()]:没有添加<a>存在title属性的筛选条件,不管子元素是否符合要求都会提取文本;//ul/li/text():会返回<li>下所有直接文本节点(包括大量空格节点),同样没有条件筛选,结果不符合预期。
验证示例
针对你提供的XML:
<ul> <li> <i> <a href="#apples" title="apples"> Apples </a> </i> (1999) </li> </ul>
使用上述XPath会精准提取出1999(或(1999),根据你选择的表达式),且仅当<a>存在title属性时才会返回结果。
内容的提问来源于stack exchange,提问作者AnchovyLegend
相关产品推荐
相关产品推荐

