Czy ktoś wie, jak uzyskać pozycję węzła za pomocą xpath?
Powiedzmy, że mam następujący plik XML:
<a>
<b>zyx</b>
<b>wvu</b>
<b>tsr</b>
<b>qpo</b>
</a>
Mogę użyć następującego zapytania xpath, aby wybrać trzeci <b> węzeł (<b> tsr </b>):
a/b[.='tsr']
Co jest w porządku, ale chcę zwrócić porządkową pozycję tego węzła, na przykład:
a/b[.='tsr']/position()
(ale trochę bardziej działa!)
Czy to w ogóle możliwe?
edycja : zapomniałem wspomnieć, że używam .net 2, więc jest to xpath 1.0!
Aktualizacja : skończyło się James Sulak „s doskonałą odpowiedź . Dla zainteresowanych moja implementacja w 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);
}
Odpowiedzi:
Próbować:
źródło
Możesz to zrobić za pomocą XSLT, ale nie jestem pewien co do prostego XPath.
<?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>
źródło
Zdaję sobie sprawę, że post jest stary ... ale ...
zastąpienie gwiazdki nazwą węzła dałoby lepsze wyniki
zamiast
źródło
Jeśli kiedykolwiek zaktualizujesz do XPath 2.0, pamiętaj, że zapewnia indeks funkcji , rozwiązuje problem w ten sposób:
Gdzie:
źródło
W przeciwieństwie do wcześniej wspomnianego „poprzedzającego rodzeństwa” jest tak naprawdę osią do użycia, a nie „poprzedzającym”, który robi coś zupełnie innego, zaznacza wszystko w dokumencie, co jest przed znacznikiem początkowym bieżącego węzła. (patrz http://www.w3schools.com/xpath/xpath_axes.asp )
źródło
Tylko notatka do odpowiedzi Jamesa Sulaka.
Jeśli chcesz wziąć pod uwagę, że węzeł może nie istnieć i chcesz, aby był on czysto XPATH, spróbuj wykonać następujące czynności, które zwrócą 0, jeśli węzeł nie istnieje.
źródło
Problem polega na tym, że pozycja węzła niewiele znaczy bez kontekstu.
Poniższy kod poda lokalizację węzła w jego nadrzędnych węzłach podrzędnych
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; } } } } }
źródło
Zajmuję się wieloma rzeczami związanymi z Novell Identity Manager i XPATH w tym kontekście wygląda trochę inaczej.
Załóżmy, że szukana wartość znajduje się w zmiennej łańcuchowej o nazwie TARGET, a XPATH będzie wyglądać tak:
Dodatkowo zwrócono uwagę, że aby zaoszczędzić kilka znaków miejsca, sprawdzą się również:
Opublikowałem również ładniejszą wersję tego na stronie Novell's Cool Solutions: Using XPATH, aby uzyskać węzeł pozycji
źródło