XPath匹配含block&result元素至首个仅block元素,兼容无终止场景
让XPath兼容有无终止元素的两种场景
嘿,我懂你遇到的问题了!你原来的XPath表达式里,[following-sibling::div[contains(@class, 'block') and not(contains(@class, 'result'))]]这个条件是强制要求存在这样的终止节点的,所以当页面里没有这个节点时,自然就匹配不到任何内容。咱们只需要把这个条件改成可选的,就能同时覆盖两种场景了。
调整后的XPath表达式
最简洁的写法是这样的:
//div[contains(@class, 'block') and contains(@class, 'result')][not(following-sibling::div[contains(@class, 'block') and not(contains(@class, 'result'))]) or following-sibling::div[contains(@class, 'block') and not(contains(@class, 'result'))]]
如果想要更精准地匹配“从第一个目标div到第一个终止div之间的所有目标div”(包括没有终止div的情况),可以用这个更严谨的版本:
//div[contains(@class, 'block') and contains(@class, 'result')] [not(following-sibling::div[contains(@class, 'block') and not(contains(@class, 'result'))]) or position() <= count(following-sibling::div[contains(@class, 'block') and not(contains(@class, 'result'))][1]/preceding-sibling::div[contains(@class, 'block') and contains(@class, 'result')])]
逻辑拆解
- 原表达式的局限:它要求每个匹配的div后面必须跟着那个仅含
block的终止div,没有的话直接过滤掉所有结果。 - 调整后的核心:通过
or not(...)把条件改成二选一:- 要么存在那个终止div,并且当前div在它之前;
- 要么根本不存在这样的终止div,此时所有带
block+result的div都应该被选中。
场景验证
- 有终止元素的示例1:和原表达式效果完全一致,只会匹配终止元素之前的所有目标div。
- 无终止元素的示例2:因为
not(following-sibling::div[...])为真,所以所有block+result的div都会被成功匹配。
内容的提问来源于stack exchange,提问作者eozzy
相关产品推荐
相关产品推荐

