【问题标题】:My XPATH expression does not work properly我的 XPATH 表达式无法正常工作
【发布时间】:2012-01-09 17:17:35
【问题描述】:

我使用这个 xpath 表达式来列出所有“非测试”项目:

/Items/Item[State!='TEST']/Name

通常输入的 XML 看起来像这样,一切正常:

<Items>
  <Item>
    <Name>Item1</Name>
    <State>ACTIVE</State>
  </Item>
  <Item>
    <Name>Item2</Name>
    <State>TEST</State>
  </Item>
</Items>

但是当 Item 未命中 State 元素时,xpath 表达式什么都不选择:

<Items>
  <Item>
    <Name>Item1</Name>
  </Item>
  <Item>
    <Name>Item2</Name>
  </Item>
</Items>

请问,我应该如何更改我的 xpath 表达式,以便在 State 元素不存在时它也可以工作?如果 State 元素不存在 Item 被认为是“NON TEST”项目。我没有选择更改 xml 结构的选项。

【问题讨论】:

    标签: xml xpath


    【解决方案1】:

    使用以下表达式:

    /Items/Item[not(State='TEST')]/Name
    

    不同之处在于State!='TEST'选择具有任何State元素且字符串值不等于TEST的项目,而not(State='TEST')选择所有不具有State元素且字符串值等于的项目TESTState 是否存在)。这是一个微妙但重要的区别。

    来自the spec

    如果要比较的一个对象是节点集,另一个是字符串, 那么当且仅当在 节点集,使得对 节点的字符串值,其他字符串为真。

    此外,想象以下输入:

    <Items>
        <Item>
            <Name>Item1</Name>
            <State>blah</State>
            <State>TEST</State>
        </Item>
        <Item>
            <Name>Item2</Name>
            <State>TEST</State>
        </Item>
    </Items>
    

    这个表达式:

    /Items/Item[State!='TEST']/Name
    

    ...将选择第一个ItemName 元素,因为它包含至少一个 State 元素不具有TEST 的值。

    但是,这个表达式:

    /Items/Item[not(State='TEST')]/Name
    

    ...不选择任何项目。这第二种形式通常是您想要的。

    请参阅此注释from the spec

    注意:如果$x 绑定到一个节点集,那么$x="foo" 并不意味着 与not($x!="foo") 相同:当且仅当 some 节点在 $x 具有字符串值foo;后者当且仅当 all 为真 $x 中的节点具有字符串值 foo

    【讨论】:

    • +1,很好的答案。您确定“State!='TEST' 选择那些(第一个)State 元素的值不等于 TEST 的项目”吗?我认为它选择了那些具有 any State 子元素整个值不等于“TEST”的项目。换句话说,我相信比较中的节点测试不会立即折叠为字符串值以排除存在比较。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 2012-05-25
    • 2016-05-09
    相关资源
    最近更新 更多