2011-01-07 13 views
21

XML:Operatore XPath "! =". Come funziona? documento

<doc> 
    <A> 
     <Node>Hello!</Node> 
    </A> 

    <B>  
     <Node/> 
    </B> 

    <C> 
    </C> 

    <D/> 
</doc> 

Come vuoi valutare i seguenti query XPath?

/doc/A/Node != 'abcd' 
/doc/B/Node != 'abcd' 
/doc/C/Node != 'abcd' 
/doc/D/Node != 'abcd' 

mi aspetterei TUTTI di questi per valutare a vero.

Tuttavia, ecco i risultati:

/doc/A/Node != 'abcd'  true 
/doc/B/Node != 'abcd'  true 
/doc/C/Node != 'abcd'  false 
/doc/D/Node != 'abcd'  false 

E` comportamento previsto? O è un bug con il mio provider XPath (jaxen)?

+0

Buona domanda, +1. Vedi la mia risposta per una spiegazione e una regola e una soluzione "da ricordare".:) –

risposta

1

Dal XPath spec:

Se un oggetto da comparare è un nodo-impostata e l'altra è una stringa, il confronto sarà vera se e solo se v'è un nodo nel node- impostare in modo tale che il risultato dell'esecuzione del confronto sul valore stringa del nodo e sull'altra stringa sia vero.

Questo significa che se il nodo-set è vuoto (come per le cause C e D), il risultato dell'espressione booleana sarà falso, poiché non v'è alcun nodo a cui può essere applicata la disuguaglianza.

È possibile aggirare il problema e ottenere il risultato desiderato utilizzando un'espressione come:

count(/doc/C/Node) = 0 or /doc/C/Node != 'abcd' 
+1

+1 Buono per la citazione delle specifiche -1 Cattivo per la raccomandazione ... –

42

Raccomandazione: Non usare mai l'operatore != per confrontare la disuguaglianza in cui uno o entrambi gli argomenti sono nodo-set.

By definition l'espressione:

$node-set != $value 

viene valutato come true() esattamente quando v'è almeno un nodo $node-set tale che il suo valore di stringa non è uguale al valore di stringa di $value.

Usando questa definizione:

$empty-nodeset != $value 

è sempre false(), perché non c'è anche un solo nodo $empty-nodeset per cui la disuguaglianza.

Soluzione:

Uso:

not($node-set = $value) 

quindi si ottiene tutti i risultati true(), come voleva.

+0

+1. Questo suggerimento mi ha già fatto risparmiare molti nervi. – Flack

+0

+1 Espressione corretta. –