2010-07-28 8 views
32

Ciao ho un file XML che è strutturato in questo modo:Che cos'è xpath per selezionare un intervallo di nodi?

<foo> 
    <bar></bar> 
    <bar></bar> 
    ... 
</foo> 

non so come per afferrare una serie di nodi. qualcuno potrebbe darmi un esempio di un'espressione xpath che afferra i nodi della barra 100-200.

+0

Buona domanda (+1). Vedere la mia risposta per una breve espressione XPath selezionando esattamente i nodi richiesti. –

risposta

53

Uso:

/*/bar[position() >= 100 and not(position() > 200)] 

Do atto:

  1. Esattamente gli bar elementi a posizione 100 a 200 (compreso) sono selezionati.

  2. La valutazione di queste espressioni XPath può essere molte volte più veloce di un'espressione usando l'abbreviazione //, poiché quest'ultima causa una scansione completa dell'albero la cui radice è il nodo di contesto. Cerca sempre di evitare l'uso della sigla // nei casi in cui ciò sia possibile.

+0

Se ricordi, potresti entrare nel tuo secondo punto? Will // e/*/restituiranno gli stessi risultati, eppure il secondo è più veloce? –

+0

@BramVanroy, sia '//' che '/ * /' sono espressioni XPath sintatticamente non valide. Suppongo che tu intendessi "// *" e/*/*. La risposta è che in questo caso specifico il tempo impiegato dovrebbe essere approssimativamente lo stesso. Tuttavia, se sono coinvolti predicati, l'espressione che include '//' dovrà scansionare un intero albero (anche i discendenti dei nodi selezionati alla fine) e filtrare ogni nodo - mentre nel caso dell'espressione esatta tale scansione viene evitata. Si noti inoltre che ci sono ** alcuni processori XPath che sono altamente ottimizzati per elaborare in modo efficiente // // * e espressioni simili. –

8
//foo/bar[100 <= position() and position() < 200] 
4

Non è fn:subsequence il modo migliore?

subsequence(/foo/bar, 100, 101) 

restituisce i lotti di posizione 100 attraverso 200, pari 101 elementi (o meno se la sequenza sorgente è più breve).

+0

Sebbene possa essere corretto, l'uso di position() in un predicato è più generale in quanto può essere applicato a più livelli. Ad esempio:/foo/bar [2 <= position() e position() <5]/x [5 <= position() e position() <10] –

+0

@DonaldRich Sì - ma ciò causa 'position()' a essere valutato ad ogni elemento della sequenza (che potrebbe essere molto più di quei 100 oggetti selezionati alla fine), mentre 'followsence()' viene chiamato solo una volta. Ad ogni modo, questo discorso riguarda "come possiamo selezionare tutti i nodi nella sequenza nelle posizioni da 100 a 200", e ** non ** riguardo "possiamo evitare di usare' position() 'per ogni possibile requisito di filtraggio di sequenze?" La mia risposta riguarda direttamente - e solo a - la domanda posta. – CiaPan

+0

@DonaldRich BTW, a patto che _deve_ 'sottosuccessione()' disponibili, la query può essere facilmente riscritta come 'sottosequenza (sottosuccessione (/ foo/bar, 2, 3)/x, 5, 5)' – CiaPan

Problemi correlati