¿Alguien sabe cómo obtener la posición de un nodo usando xpath?
Digamos que tengo el siguiente xml:
<a>
<b>zyx</b>
<b>wvu</b>
<b>tsr</b>
<b>qpo</b>
</a>
Puedo usar la siguiente consulta xpath para seleccionar el tercer <b> nodo (<b> tsr </b>):
a/b[.='tsr']
Lo cual está muy bien, pero quiero devolver la posición ordinal de ese nodo, algo como:
a/b[.='tsr']/position()
(¡pero un poco más de trabajo!)
¿Es siquiera posible?
editar : ¡Olvidé mencionar que 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);
}
Respuestas:
Tratar:
fuente
Puede hacer esto con XSLT pero no estoy seguro acerca de XPath directo.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/> <xsl:template match="a/*[text()='tsr']"> <xsl:number value-of="position()"/> </xsl:template> <xsl:template match="text()"/> </xsl:stylesheet>
fuente
Me doy cuenta de que la publicación es antigua .. pero ..
reemplazar el asterisco con el nombre de nodo le daría mejores resultados
en vez de
fuente
Si alguna vez actualiza a XPath 2.0, tenga en cuenta que proporciona índice de función , resuelve el problema de esta manera:
Dónde:
fuente
A diferencia de lo que se indicó anteriormente, 'hermano anterior' es realmente el eje a usar, no 'precedente' que hace algo completamente diferente, selecciona todo en el documento que está antes de la etiqueta de inicio del nodo actual. (consulte http://www.w3schools.com/xpath/xpath_axes.asp )
fuente
Solo una nota a la respuesta hecha por James Sulak.
Si desea tener en cuenta que es posible que el nodo no exista y desea mantenerlo puramente XPATH, intente lo siguiente que devolverá 0 si el nodo no existe.
fuente
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 secundarios 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; } } } } }
fuente
Hago muchas cosas de 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:
Además, se señaló que para ahorrar algunos caracteres de espacio, lo siguiente también funcionaría:
También publiqué una versión más bonita de esto en Novell's Cool Solutions: Using XPATH to get the position node
fuente