XPath中contains(text())与或运算符(|)结合使用失效问题咨询
解决XPath中结合
contains()与|运算符失效的问题 我来帮你搞定这个问题——你遇到的失效情况其实是对XPath里|运算符的用法理解有偏差导致的,咱们一步步拆解:
首先先复现你遇到的场景(基于rvest的测试代码):
library(rvest) html <- "<a>a</a><p>abc</p>" xp <- "//*[self::a|self::b]" # 或运算符可正常工作 xp2 <- "//*[contains(text(),'abc')]" # 文本匹配函数可正常工作 # 但二者结合使用时失效 xp3 <- "//*[self::a|contains(text(),'abc')]" html_nodes(x = read_html(html), xpath = xp) html_nodes(x = read_html(html), xpath = xp2) # 此语句执行失败 html_nodes(x = read_html(html), xpath = xp3)
为什么xp3会失效?
XPath里的|是节点集的并集运算符,它要求运算符两边必须都是节点集,而contains(text(), 'abc')返回的是一个布尔值(true/false),不是节点集,所以self::a | contains(...)这种写法违反了XPath的语法规则,自然会执行失败。
两种正确的写法
方法1:用or连接布尔筛选条件
如果是想在同一个节点范围内,筛选满足「是<a>标签」或「文本包含'abc'」的节点,直接用or连接两个布尔条件即可:
xp_fixed1 <- "//*[self::a or contains(text(), 'abc')]" result1 <- html_nodes(read_html(html), xpath = xp_fixed1) # 输出会匹配到<a>a</a>和<p>abc</p>两个节点
方法2:用|连接两个完整的节点路径
如果是想取「所有<a>标签」和「所有文本包含'abc'的节点」的并集,就把两个完整的节点选择表达式用|连接(两边都是节点集):
xp_fixed2 <- "//a | //*[contains(text(), 'abc')]" result2 <- html_nodes(read_html(html), xpath = xp_fixed2) # 同样能得到正确的匹配结果
两种方法都能达到你想要的效果,你可以根据实际需求选择合适的写法~
内容的提问来源于stack exchange,提问作者Tlatwork
相关产品推荐
相关产品推荐

