XPath校验XHTML元素父节点问题求助:class为block的元素需以p为父节点,现有XPath因兄弟p元素干扰失效
解决XPath校验class为block元素父节点必须是p标签的问题
问题根源
你原来的XPath逻辑完全搞反了:parent::*[not(p)]是在判断父元素是否没有<p>子元素,而不是判断父元素本身是不是<p>标签。这就导致当父元素(比如你例子里的<div>)下面存在<p>兄弟元素时,这个条件会返回false,自然找不到不符合要求的<kbd class="block">元素。
正确的XPath写法
我们需要直接校验父元素的节点类型是否为<p>,而不是它的子元素。推荐两种靠谱的写法:
写法1:使用self::节点测试(更严谨)
.//*[contains(concat(" ", normalize-space(@class), " "), " block ")]/parent::*[not(self::p)]
not(self::p):明确判断当前父节点本身不是<p>标签,完全贴合你的校验需求,即使遇到带命名空间的XML也能正常工作。
写法2:直接判断节点名称(适合无命名空间场景)
.//*[contains(concat(" ", normalize-space(@class), " "), " block ")]/parent::*[name() != 'p']
name() != 'p':通过节点名称判断父元素不是<p>,你的XHTML文档没有命名空间,用这种写法足够简洁有效。
验证你的示例文档
用上面任意一种XPath查询你提供的XHTML文档时,会精准匹配到<kbd class="block">的父元素<div>——这正是你要找的不符合要求的情况。
内容的提问来源于stack exchange,提问作者Mattias Sander
相关产品推荐
相关产品推荐

