Encontrar la posición de un nodo usando xpath

¿Alguien sabe cómo obtener la posición de un nodo usando xpath?

Digamos que tengo el siguiente xml:

 zyx wvu tsr qpo  

Puedo usar la siguiente consulta xpath para seleccionar el tercer nodo ( tsr ):

 a/b[.='tsr'] 

Lo cual está muy bien, pero quiero devolver la posición ordinal de ese nodo, algo así como:

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

(¡pero un poco más funcionando!)

¿Es posible?

editar : Olvidé mencionar estoy usando .net 2 así que es xpath 1.0!


Actualización : terminó usando la excelente respuesta de James Sulak . Para aquellos que están interesados ​​aquí está mi implementación en 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); } 

Tratar:

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

Puedes hacer esto con XSLT pero no estoy seguro acerca de XPath directo.

 < ?xml version="1.0" encoding="UTF-8" standalone="yes"?>        

Me doy cuenta de que la publicación es antigua … pero …

reemplazar el asterisco con el nombre del nodo le daría mejores resultados

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

en lugar de

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

A diferencia de lo que se dijo previamente ‘hermano anterior’ es realmente el eje que se debe usar, no ‘precedente’, que hace algo completamente diferente, selecciona todo en el documento que está antes de la etiqueta de inicio del nodo actual. (vea http://www.w3schools.com/xpath/xpath_axes.asp )

Si alguna vez actualiza a XPath 2.0, tenga en cuenta que proporciona el índice de función, resuelve el problema de esta manera:

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

Dónde:

  • El primer parámetro es la secuencia para buscar
  • 2.º es qué buscar

El problema es que la posición del nodo no significa mucho sin un contexto.

El siguiente código le dará la ubicación del nodo en sus nodos hijos principales

 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 a la respuesta hecha por James Sulak.

Si desea tener en cuenta que el nodo puede no existir y desea mantenerlo puramente XPATH, intente lo siguiente que devolverá 0 si el nodo no existe.

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

Hago muchas cosas sobre Novell Identity Manager, y XPATH en ese contexto se ve un poco diferente.

Suponga que el valor que está buscando está en una variable de cadena, llamada TARGET, entonces el XPATH sería:

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

Además, se señaló que para ahorrar algunos caracteres de espacio, lo siguiente también funcionaría:

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

También publiqué una versión más bonita de esto en Cool Solutions de Novell: Usando XPATH para obtener el nodo de posición