简体   繁体   中英

XPath - Difference between 'not' and '!='

Just a quick question as to the difference between xpath's 'not' and '!=' in the following content.

Taking the XML:

<years>
  <year value="2010"></year>
  <year value="2010"></year>
  <year value="2010"></year>
  <year value="2009"></year>
</years>

I want to select unique years. I have struggled for a while to achieve this, but managed in the end, but in a curious way that I did not expect.

The following xpath is correct for my intention and returns two unique year nodes of 2009 and 2010.

years/year[not(@value = preceding-sibling::year/@value)]

The following only returns the 2009 year node.

years/year[@value != preceding-sibling::year/@value]

The only difference between them is the != and not operators. I've pondered on this a while and I can't find a difference that I could satisfactorily explain to anyone else.

Perhaps someone could help.

Cheers

Steve

The second example does not work because if you apply it to each of the first 3 nodes, it never matches. For the first <year> , there's no preceding sibling whose value one might try to compare to, so it fails to match. For the second and third, their preceding node does have the same value, so the non-equality test fails and leads to no match again.

The not(...) version works because in the first node, the whole @value = preceding-sibling::year/@value fails due to the lack of a preceding sibling, and this failure in inverted by not , giving you a match on the first node.

In XPath, a != b and not(a = b) are VERY different

Here's why

From the spec for XPath 1.0:

If both objects to be compared are node-sets, then the comparison will be true if and only if there is a node in the first node-set and a node in the second node-set such that the result of performing the comparison on the string-values of the two nodes is true.

that means that (a = b) for node sets is true if there is a match between any element in a and b.
(a != b) means that some element in a DOES NOT match some element in b. so for the node sets A = (1, 2), B = (1, 2). BOTH a = b and a != b will return true.

In your case what's happening is that (2010 != empty set) is always false, while
not (2010 = empty set) is always true. Think about the matching rules as above.

我不是xpath的专业人士,但我认为'not'重新计算包含事物的倒置值,而!=返回两个可比较事物之间的比较值

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM