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

Voj*_*ech 3 xml xpath

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

/Items/Item[State!='TEST']/Name
Run Code Online (Sandbox Code Playgroud)

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

<Items>
  <Item>
    <Name>Item1</Name>
    <State>ACTIVE</State>
  </Item>
  <Item>
    <Name>Item2</Name>
    <State>TEST</State>
  </Item>
</Items>
Run Code Online (Sandbox Code Playgroud)

但是当Item miss State元素时,xpath表达式什么都不选:

<Items>
  <Item>
    <Name>Item1</Name>
  </Item>
  <Item>
    <Name>Item2</Name>
  </Item>
</Items>
Run Code Online (Sandbox Code Playgroud)

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

Way*_*ett 5

使用以下表达式:

/Items/Item[not(State='TEST')]/Name
Run Code Online (Sandbox Code Playgroud)

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

规格:

如果要比较的一个对象是节点集而另一个是字符串,那么当且仅当节点集中有节点时才进行比较,以便对字符串值执行比较的结果节点和另一个字符串是真的.

此外,想象以下输入:

<Items>
    <Item>
        <Name>Item1</Name>
        <State>blah</State>
        <State>TEST</State>
    </Item>
    <Item>
        <Name>Item2</Name>
        <State>TEST</State>
    </Item>
</Items>
Run Code Online (Sandbox Code Playgroud)

这个表达式:

/Items/Item[State!='TEST']/Name
Run Code Online (Sandbox Code Playgroud)

...将选择第一ItemName元件,因为它包含至少一种 State不具有值元件TEST.

但是,这个表达式:

/Items/Item[not(State='TEST')]/Name
Run Code Online (Sandbox Code Playgroud)

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

请参阅规范中的此注释:

注意:如果$x绑定到节点集,$x="foo"则不等同于not($x!="foo"):当且仅当某个节点 $x具有字符串值时foo,前者才为真; 当且仅当所有 节点$x都具有字符串值时,后者才是真的foo.