You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XPath中|运算符未按预期生效的技术问题求助

XPath优先级提取前序兄弟/祖先节点@id的正确写法

需求说明

作为XPath新手,需要提取目标节点的前序兄弟节点的@id属性;若不存在该兄弟节点,则提取其祖先节点的@id。

目标XML

<?xml version="1.0" encoding="utf-8"?>
<root>
  <parent class="InfoType01" id="1">
    <p>11</p>
        <node class="InfoType01" id="2">
            <p>22</p>
        </node>
        <node class="InfoType01" id="3">
            <p>33</p>
        </node>
  </parent>
</root>

原表达式问题

原使用的XPath表达式:

//node[contains(p, '33')]/preceding-sibling::node[@class='InfoType01'][1]/@id
| 
//node[contains(p, '33')]/ancestor::*[@class='InfoType01']/@id

两个表达式单独执行均正常,但合并后无论第一个表达式是否有结果,都会返回第二个表达式的结果。这是因为误解了|运算符的作用:XPath中的|是节点集合并运算符,会将两个表达式的结果合并去重,而非短路判断(仅第一个无结果时执行第二个)。

正确解决方案

方案1:XPath 2.0+ 支持的if-else逻辑

利用XPath 2.0及以上版本的条件判断语法,实现短路逻辑:

if (//node[contains(p, '33')]/preceding-sibling::node[@class='InfoType01'][1])
then //node[contains(p, '33')]/preceding-sibling::node[@class='InfoType01'][1]/@id
else //node[contains(p, '33')]/ancestor::*[@class='InfoType01']/@id

方案2:兼容XPath 1.0的写法

通过给第二个表达式添加条件,仅当目标节点没有符合要求的前序兄弟时才执行:

//node[contains(p, '33')]/preceding-sibling::node[@class='InfoType01'][1]/@id
|
//node[contains(p, '33')][not(preceding-sibling::node[@class='InfoType01'])]/ancestor::*[@class='InfoType01']/@id

这样合并后,只会返回前序兄弟的@id(存在时),或祖先节点的@id(无前序兄弟时)。

内容的提问来源于stack exchange,提问作者I0sens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 23:33:10