2010-04-20 11 views
9

Come faccio ad usare qualcosa di simile all'esempio qui sotto, ma con il risultato opposto, cioè gli articoli che non contengono (default) nel testo.Come costruire un xpath per selezionare elementi che non contengono una stringa

<test> 
    <item>Some text (default)</item> 
    <item>Some more text</item> 
    <item>Even more text</item> 
</test> 

Dato questo

//test/item[contains(text(), '(default)')] 

sarebbero ritornati la prima voce. C'è un operatore che non posso usare con contiene?

risposta

17

Sì, c'è:

//test/item[not(contains(text(), '(default)'))]

Suggerimento: not() è una funzione in XPath, invece di un operatore.


Un'alternativa, modo forse meglio esprimere questo è:

//test/item[not(text()[contains(., '(default)')])]

C'è una differenza sottile ma importante tra le due espressioni (chiamiamoli A e B, rispettivamente).

Caso semplice: Se tutti gli <item> hanno un solo nodo di testo figlio, entrambi A e B si comportano allo stesso modo.

caso complesso: Se <item> può avere molteplici figli del nodo di testo, l'espressione A partite solo quando '(default)' si verifica nel primo di essi.

Questo perché text() corrisponde a tutti i nodi del nodo di testo e genera un set di nodi. Finora nessuna sorpresa. Ora, accetta un set di nodi come primo argomento, ma è necessario convertirlo in stringa per eseguire il proprio lavoro. E la conversione da node-set a string produce solo il valore stringa del primo nodo nel set, tutti gli altri nodi vengono ignorati (prova string(//item) per vedere cosa intendo). Nel caso semplice questo è esattamente ciò che accade, ma il risultato non è così sorprendente.

L'espressione B risolve questo problema controllando esplicitamente ciascun nodo di testo singolarmente anziché controllare solo il valore di stringa dell'intero elemento <item>. È quindi il più robusto dei due.

Problemi correlati