【问题标题】:XPath expression to select a node if attribute matches, or a node without this attribute otherwise如果属性匹配则选择节点的 XPath 表达式,否则选择没有此属性的节点
【发布时间】:2013-10-11 10:36:39
【问题描述】:

考虑以下 XML

<xml>
  <tag/>
  <tag version="2.1"/>
</xml>

我想要一个 XPath 1.0 表达式,如果我搜索版本 2.1,则返回 &lt;tag version="2.1"/&gt;,如果我搜索版本 2.2,则返回 &lt;tag/&gt;

到目前为止,我已经尝试过

/xml/tag[@version = '%version%' or not(@version)]

其中%version% 是一个可以是2.1 或2.2 的字符串,但如果%version% 是2.1,它会返回两个节点。

【问题讨论】:

  • 2.1 上搜索会返回两者,因为在您的xpath 中您执行or not(@version),这将导致标签没有属性。因此,传递给%version% 的内容并不重要,因为&lt;tag/&gt; 总是会因为or 语句而被返回......你试图实现的目标在一个XPath 语句中是不可能的。应该在代码中解决

标签: xml xpath


【解决方案1】:

你可以使用这样的东西,使用|(或)

    /xml[not(tag[@version="2.1"])]/tag[not(@version)] |
    /xml[tag[@version="2.1"]]/tag[@version="2.1"]
  • xml 没有tags 和version="2.1",然后返回tags 没有version 属性
  • 或者,如果xml 确实包含tags 和version="2.1",则返回这些

你的情况就是这样

    /xml[not(tag[@version='%version%'])]
        /tag[not(@version)]
    |
    /xml[tag[@version='%version%']]
        /tag[@version='%version%']

【讨论】:

    【解决方案2】:

    作为 xpath 2.0(如果相关)替代非常好的@paul 答案,您可以使用

    if (/xml/tag[@version = '2.1']) then /xml/tag[@version = '2.1'] else /xml/tag[not(@version)] 
    

    分别

    if (/xml/tag[@version = '%version%']) then /xml/tag[@version = '%version'] else /xml/tag[not(@version)] 
    

    【讨论】:

    • 这确实是一个很好的选择,不幸的是我不能使用 xpath 2.0。我已经相应地更新了我的问题。
    猜你喜欢
    • 2010-11-22
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 2013-11-30
    • 1970-01-01
    相关资源
    最近更新 更多