Come selezionare un nodo utilizzando XPath se il nodo di pari livello ha un valore specifico?


89

Ho il seguente documento:

<a>
  <bb>abc</bb>
  <cc>ccc</cc>
  <dd>ddd</dd>
</a>
<a>
  <bb>zz</bb>
  <cc>1</cc>
  <dd>2</dd>
</a>

Come posso ottenere il valore <cc>dell'utilizzo di XPath se lo <bb>è zz?


1
il problema è che so come accedere a un nodo specifico, ma non ho idea di accedere a un nodo se un fratello ha un valore specifico. Può essere qualcosa del genere / a / cc / contains (/ a / bb = 'zz')?
HOE SENGKIANG

Risposte:


101

Non sei sicuro del motivo per cui tutti stanno interrogando i fratelli, puoi anche controllare gli <bb/>-elementi che corrispondono al predicato dal <a/>predicato di:

//a[bb/text() = "zz"]/cc/text()

24
"Non sono sicuro del motivo per cui tutti chiedono i fratelli" : Forse perché la domanda era per i fratelli .. ;-)
hr_117

4
Sembra che in realtà non abbia letto il titolo. :) La risposta rimane comunque valida.
Jens Erat,

2
Le tue domande di risposta anche per i fratelli. Semplicemente non hai usato un *-siblingasse. +1 però.
LarsH

Questo non risponde alla domanda ma risponde alla mia domanda reale che ho formulato male. Grazie!
Utente9213


24

D: Come selezionare un nodo utilizzando XPath se il nodo di pari livello ha un valore specifico?
Poiché ci sono solo "XPath Axes" per i seguenti fratelli e sorelle precedenti, puoi usarne uno se la posizione è fissa.

Ma meglio: cerca dove ccil genitore ha un figlio bbcon valore 'zz':

//cc[../bb='zz']

6
O quello o //a[bb = 'zz']/cc.
Tomalak,

Non sono sicuro di cosa intendi per "solo" XPath Axes "per il fratello successivo e il fratello precedente". Ti riferisci al fatto che non esiste un unico asse per tutti i fratelli?
LarsH

@ LarsH: Sì, scusa, (scusa il mio cattivo inglese :-() - era quello che stavo cercando di dire. (Perché la domanda era per i fratelli)
hr_117

6

Prima di tutto, il tuo esempio non è un XML ben formato. Trascurando questo e che non hai descritto molto bene i tuoi intenti (cosa vuoi selezionare esattamente a quale condizione?), Presumo che tu voglia fare questo:

//cc[preceding-sibling::bb[text()="zz"]]/text()

Seleziona

TEXT VALUES OF ALL <CC> ELEMENTS
//cc                                    /text()
    THAT HAVE A PRECEDING SIBLING <BB>
    [preceding-sibling::bb             ]
                          THAT HAS TEXT VALUE EQUAL TO "zz"
                          [text()="zz"]

Potresti scrivere anche come

//bb[text()="zz"]/following-sibling::cc/text()

Per favore guarda le specifiche , ha alcuni esempi molto ben leggibili dai quali imparerai molto.


1
@LarsH Grazie per la correzione da "non valido" a "non ben formato". Oggi ho imparato qualcosa di nuovo.
Petr Janeček

4
//a/cc[../bb='zz']/text()

// a: seleziona tutti gli elementi "a" indipendentemente da dove si trovano.

// a / cc: seleziona gli elementi "cc" che sono figli dell'elemento "a" (indipendentemente da dove si trova a).

..: seleziona il genitore del nodo corrente.

[../bb='zz ']: dove il valore dell'elemento "bb" di pari livello è zz.

Riferimento: http://www.w3schools.com/xsl/xpath_syntax.asp


4

Un'altra soluzione per questo problema è

//bb[contains(.,'zz')]/../cc/text()

Spiegazione : Qualsiasi bbche contenga una 'zz'stringa in tutti i nodi figlio che bbva poi al nodo genitore di quello bbutilizzando .., ora che possiamo accedere alcc testo così restituito.

Spero che la spiegazione non sia complessa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.