XPath如何通过兄弟节点区分XML同名节点 定位无前置兄弟的C元素
需求说明
给定如下XML结构,需要仅匹配第一个<B>标签下的<C/>元素,排除第二个<B>标签下跟在<D/>后的<C/>元素,匹配规则为目标C元素不存在同父级下的前置兄弟元素节点。
示例XML:
<A> <B> <C/> <!-- 目标匹配节点 --> </B> <B> <D/> <C/> <!-- 需要排除的节点 --> </B> </A>
符合XPath规范的实现写法
直接使用以下XPath表达式即可实现需求:
//C[not(preceding-sibling::*)]
写法逻辑说明
//C:匹配文档中所有层级的C元素- 谓词判断
[not(preceding-sibling::*)]:筛选出不存在任何元素类型前置兄弟节点的C元素:preceding-sibling::是XPath的标准轴,用于选取当前节点的父节点下、排在当前节点之前的所有同层级节点- 轴后面的
*通配符仅匹配元素类型节点,会自动忽略缩进用的空白文本节点、注释、处理指令,适配绝大多数格式化排版的XML场景 not()函数对前置兄弟元素的存在结果取反,只有前置兄弟元素数量为0的C节点会被选中
特殊场景适配
如果你的XML解析器配置为严格识别所有节点类型(包括空白文本、注释等),且你要求目标C节点前不能有任何类型的前置兄弟(哪怕是空格、注释),可以使用以下严格匹配写法,注意该写法在常规缩进排版的XML中可能匹配不到目标:
//C[not(preceding-sibling::node())]
常见误区提醒
不要误用preceding轴替代preceding-sibling轴:preceding轴会匹配整个文档中出现在当前节点之前的所有非祖先、非自身、非后代节点,范围远大于同父级的兄弟节点,会导致匹配结果不符合预期。
内容的提问来源于stack exchange,提问作者Brudi90
相关产品推荐
相关产品推荐

