问题
XML document:
<doc>
<A>
<Node>Hello!</Node>
</A>
<B>
<Node/>
</B>
<C>
</C>
<D/>
</doc>
How would you evaluate the following XPath queries?
/doc/A/Node != 'abcd'
/doc/B/Node != 'abcd'
/doc/C/Node != 'abcd'
/doc/D/Node != 'abcd'
I would expect ALL of these to evaluate to true.
However, here are the results:
/doc/A/Node != 'abcd' true
/doc/B/Node != 'abcd' true
/doc/C/Node != 'abcd' false
/doc/D/Node != 'abcd' false
Is this expected behavior? Or is it a bug with my XPath provider (jaxen)?
回答1:
Recommendation: Never use the !=
operator to compare inequality where one or both arguments are node-sets.
By definition the expression:
$node-set != $value
evaluates to true()
exactly when there is at least one node in $node-set
such that its string value is not equal to the string value of $value
.
Using this definition:
$empty-nodeset != $value
is always false()
, because there isn't even a single node in $empty-nodeset
for which the inequality holds.
Solution:
Use:
not($node-set = $value)
Then you get all results true()
, as wanted.
回答2:
From the XPath spec:
If one object to be compared is a node-set and the other is a string, then the comparison will be true if and only if there is a node in the node-set such that the result of performing the comparison on the string-value of the node and the other string is true.
This means that if the node-set is empty (as in your cases C and D), the result of the boolean expression will be false, since there is no node to which the inequality can apply.
You can work around this behaviour and get the result you want using an expression like:
count(/doc/C/Node) = 0 or /doc/C/Node != 'abcd'
来源:https://stackoverflow.com/questions/4629416/xpath-operator-how-does-it-work