Trova la posizione di un nodo usando xpath

Qualcuno sa come ottenere la posizione di un nodo usando xpath?

Dì che ho il seguente xml:

 zyx wvu tsr qpo  

Posso usare la seguente query xpath per selezionare il terzo nodo ( tsr ):

 a/b[.='tsr'] 

Che va tutto bene ma voglio tornare alla posizione ordinale di quel nodo, qualcosa del tipo:

 a/b[.='tsr']/position() 

(ma un po ‘più di lavoro!)

È ansible?

edit : Ho dimenticato di usare me .net 2 quindi xpath 1.0!


Aggiornamento : finito con l’ eccellente risposta di James Sulak . Per quelli che sono interessati ecco la mia implementazione in C #:

 int position = doc.SelectNodes("a/b[.='tsr']/preceding-sibling::b").Count + 1; // Check the node actually exists if (position > 1 || doc.SelectSingleNode("a/b[.='tsr']") != null) { Console.WriteLine("Found at position = {0}", position); } 

Provare:

 count(a/b[.='tsr']/preceding-sibling::*)+1. 

Puoi farlo con XSLT ma non sono sicuro di XPath diretto.

         

Mi rendo conto che il post è antico .. ma ..

sostituire l’asterisco con il nomenodo ti darebbe risultati migliori

 count(a/b[.='tsr']/preceding::a)+1. 

invece di

 count(a/b[.='tsr']/preceding::*)+1. 

A differenza di quanto affermato in precedenza, “precedente-fratello” è in realtà l’asse da utilizzare, non “precedente” che fa qualcosa di completamente diverso, seleziona tutto nel documento che precede il tag di inizio del nodo corrente. (vedi http://www.w3schools.com/xpath/xpath_axes.asp )

Se si esegue l’aggiornamento a XPath 2.0, si noti che fornisce l’ indice di funzione, risolve il problema in questo modo:

 index-of(//b, //b[.='tsr']) 

Dove:

  • Il primo parametro è la sequenza per la ricerca
  • Il secondo è cosa cercare

Il problema è che la posizione del nodo non significa molto senza un contesto.

Il codice seguente ti darà la posizione del nodo nei suoi nodes figli principali

 using System; using System.Xml; public class XpathFinder { public static void Main(string[] args) { XmlDocument xmldoc = new XmlDocument(); xmldoc.Load(args[0]); foreach ( XmlNode xn in xmldoc.SelectNodes(args[1]) ) { for (int i = 0; i < xn.ParentNode.ChildNodes.Count; i++) { if ( xn.ParentNode.ChildNodes[i].Equals( xn ) ) { Console.Out.WriteLine( i ); break; } } } } } 

Solo una nota alla risposta fatta da James Sulak.

Se si desidera prendere in considerazione che il nodo potrebbe non esistere e si desidera mantenerlo puramente XPATH, quindi provare quanto segue che restituirà 0 se il nodo non esiste.

 count(a/b[.='tsr']/preceding-sibling::*)+number(boolean(a/b[.='tsr'])) 

Faccio molte cose di Novell Identity Manager e XPATH in quel contesto sembra un po ‘diverso.

Supponiamo che il valore che stai cercando sia in una variabile stringa, chiamato TARGET, quindi XPATH sarebbe:

 count(attr/value[.='$TARGET']/preceding-sibling::*)+1 

Inoltre è stato sottolineato che per salvare alcuni caratteri di spazio, il seguente potrebbe funzionare anche:

 count(attr/value[.='$TARGET']/preceding::*) + 1 

Ho anche pubblicato una versione più carina di questo a Novell’s Cool Solutions: Utilizzo di XPATH per ottenere il nodo posizione