XPath operator "!=". How does it work?

47,817

Solution 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.

Solution 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'
Share:
47,817
Admin
Author by

Admin

Updated on January 08, 2020

Comments

  • Admin
    Admin almost 4 years

    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)?