2009-02-17 10 views
15
<Document> 
    <A> 
    <B> 
     <C></C> 
    </B> 
    </A> 
    <E> 
    <F> 
    <C></C> 
    </F> 
    <G> 
    <C></C> 
    </G> 
</E> 
</Document> 

se carico il codice XML sopra in un XmlDocument e fare un SelectSingleNode su A utilizzando la query XPath // CSelectNodes XPath in .NET

 
XmlNode oNode = oDocument.SelectSingleNode("E"); 
XmlNodeList oNodeList = oNode.SelectNodes("//C"); 

perché lo fa tornare i nodi da Under B quando ciò che Mi aspetto che succeda che restituisca solo i nodi da E

Ha senso?

Modifica: come faccio a tornare solo da quel nodo in poi?

risposta

22

Semplicemente: un // principale indica "a qualsiasi livello" nello stesso documento come nodo selezionato.

Dal spec:

  • // para seleziona tutti i discendenti para della radice del documento e quindi seleziona tutti gli elementi para nello stesso documento come nodo di contesto
  • .//para seleziona la para discendenti dell'elemento del nodo di contesto
11

La specifica di .//C consente di ottenere ciò che si desidera, altrimenti XPath viene avviato dalla radice del documento anziché dal nodo corrente.

La confusione è nella definizione // dalla XPath standard come segue:

// è l'abbreviazione di /descendant-or-self :: node() /. Per esempio , // para è l'abbreviazione di /descendant-or-self :: node()/child :: para e selezionerà quindi qualsiasi elemento para in il documento (anche un elemento para che è un elemento documento sarà selezionato da // para poiché il nodo elemento documento è figlio del nodo radice); div // para è l'abbreviazione di div/descendant-or-self :: node()/child :: para e quindi selezionerà tutti i discendenti di para figli div.

Perché // è l'abbreviazione di /descendant-or-self::node()/ inizia a livello di documento se non si specifica un nodo alla partenza.

+0

No, la specifica dice "//" è "della radice del documento", e ".//" è del nodo di contesto. L'implementazione è corretta. –

+0

Rif. Ref. W3: leggere attentamente: "nel documento dal nodo corrente" - il nodo contesto viene utilizzato (solo) per ottenere il documento; quindi l'intero documento viene scansionato. –

+0

Sì, l'ho aggiornato per fare riferimento allo standard XPath ed evidenziare dove si trova la confusione. Grazie. :) –

6

//C è tutti i nodi C nell'intero documento

/E//C sarebbe solo nodi C sotto E

/C sarebbe solo il nodo radice C

Vedere la xpath syntax reference

3

Nel XPATH Specification troverete sotto 2.5 la seguente istruzione:

// para seleziona tutti i para discendenti della radice del documento e seleziona quindi tutti gli elementi para nello stesso documento come nodo di contesto

cioè il comportamento osservare è valido. Si dovrebbe fare qualcosa come "/ E // C"

+0

E se non sapessi quanti nodi sono stati profondi in C? Potrebbe essere/E/D/G/C? –

+0

@Gordon - "/ E // C" gestirà qualsiasi numero di livelli tra E e C. –