我的XPATH表达式无法正常工作

时间:2012-01-09 17:17:35

标签: xml xpath

我使用此xpath表达式列出所有“NON TEST”项:

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

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

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

但是当项目未命中状态元素时,xpath表达式不会选择任何内容:

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

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

1 个答案:

答案 0 :(得分:5)

使用以下表达式:

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

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

来自the spec

  

如果要比较的一个对象是节点集而另一个是字符串,   那么当且仅当有一个节点时,比较才会成立   node-set使得执行比较的结果   节点的字符串值和另一个字符串为真。

此外,想象一下以下输入:

<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

...将选择第一个Item的{​​{1}}元素,因为它包含至少一个 Name元素,其值不是{{ 1}}。

但是,这个表达式:

State

...不选择任何物品。第二种形式通常是你想要的。

请参阅此说明from the spec

  

注意:如果TEST绑定到节点集,那么/Items/Item[not(State='TEST')]/Name 并不意味着   与$x相同:当且仅当某些节点时,前者才是真的   $x="foo"具有字符串值not($x!="foo");当且仅当 all 时,后者才是真的   $x中的节点具有字符串值foo