2012-06-30 13 views
7

Jak uzyskać położenie węzła nadrzędnego w całym dokumencie za pomocą xpath?Znajdź pozycję węzła nadrzędnego, używając xpath

że mam następujące xml:

<catalog> 
    <cd> 
    <title>Empire Burlesque</title> 
    <artist>Bob Dylan</artist> 
    <country>USA</country> 
    <company>Columbia</company> 
    <price>10.90</price> 
    <year>1985</year> 
    </cd> 
    <cd> 
    <title>Hide your heart</title> 
    <artist>Bonnie Tyler</artist> 
    <country>UK</country> 
    <company>CBS Records</company> 
    <price>9.90</price> 
    <year>1988</year> 
    </cd> 
</catalog> 

i mam XSLT do przekształcenia go w HTML, który jest następujący (tylko urywek):

<xsl:template match="/"> 
<html> 
    <body> 
    <xsl:apply-templates/> 
    </body> 
    </html> 
</xsl:template> 

<xsl:template match="cd"> 
    <p> 
    <xsl:number format="1. "/><br/> 
    <xsl:apply-templates select="title"/> 
    <xsl:apply-templates select="artist"/> 
    </p> 
</xsl:template> 

<xsl:template match="title"> 
    <xsl:number format="1" select="????" /><br/> 
    Title: <span style="color:#ff0000"> 
    <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

Co powinienem napisać w miejsce ???? aby uzyskać pozycję macierzystego znacznika cd w dokumencie. Próbowałem wielu wyrażeń, ale nic nie działa. Być może robię to zupełnie źle.

  1. <xsl:number format="1" select="catalog/cd/preceding-sibling::..[position()]" />
  2. <xsl:number format="1" select="./parent::..[position()]" /><br/>
  3. <xsl:value-of select="count(cd/preceding-sibling::*)+1" /><br/>

ja interpretacji 2nd jako oś dominujących wybierz Aktualna węzła, a następnie powiedzieć pozycję rodzica bieżącego węzła. Dlaczego to nie działa? Jaki jest właściwy sposób, aby to zrobić.

FYI: Oczekuję, że kod wydrukuje pozycję nadrzędnego znacznika cd bieżącego przetwarzania tagu tytułu.

Czy ktoś może mi powiedzieć, jak to zrobić.

Odpowiedz

16
count(../preceding-sibling::cd) + 1 

Można run it here (nota usunąłem inny numer pan wyprowadzanie tylko dla jasności).

Byłeś na właściwej linii, ale pamiętaj, że predykaty służą tylko do filtrowania węzłów, a nie do zwracania informacji. A więc:

../*[position()] 

... skutecznie mówi "znajdź mi rodzica, który ma pozycję". Zwraca węzeł, a nie samą pozycję. Predykat jest tylko filtrem.

W każdym razie istnieją pułapki przy użyciu position() i można go użyć do zwrócenia pozycji bieżącego węzła kontekstowego tylko - bez innego węzła.

+0

Dzięki ton mężczyzna, teraz to było głupie z mojej strony, aby nie spróbować. Jeszcze raz dziękuję :) – Harshdeep

+0

Jeszcze jedno, czy możesz wyjaśnić wyrażenie "count (../ previous-sibling :: cd) + 1" jak w przypadku "position()". Użyłem twojego rozwiązania i działało świetnie, ale nie jestem w stanie zrozumieć, dlaczego nie "count (cd/previous-sibling :: ..) + 1" – Harshdeep

+2

Pamiętaj, że szablony XSLT działają z perspektywy bieżącego węzła kontekstu. W danym szablonie węzeł kontekstu jest tytułem. Dlatego 'count (cd ...)' nie znajdzie żadnych węzłów, ponieważ nie ma węzłów potomnych 'title' zwanych' cd' (w rzeczy samej 'title' nie ma żadnych węzłów potomnych o żadnej nazwie). 'cd' jest rodzicem' title', a nie jego dzieckiem, dlatego musimy podnieść poziom. – Utkanos

1
<xsl:number format="1" select="????" /> 

Co mam napisać w miejscu ???? aby uzyskać pozycję rodzica znacznika cd w dokumencie.

Przede wszystkim, powyższe wskazówki XSLT jest składniowo nielegalne - dyspozycja <xsl:number> nie (nie mogą) mieć atrybutselect.

Zastosowanie: odpowiedź

<xsl:number format="1" count="cd" /> 
+0

Można to również zrobić, używając xsl: number. Dzięki za informację. możesz podać więcej informacji o tym, jak to działa. – Harshdeep

+0

@Harshdeep: Najlepiej nauczyć się "jak to działa" klikając na link (tak, niebieski kolor '' w odpowiedzi oznacza, że ​​jest to klikalny link). Aby zobaczyć wyniki użycia tej instrukcji, skopiuj i wklej ją do kodu. –

+0

Zrobiłem kliknięcie linku przed pytaniem, ale dokumentacja w3 jest tak obszerna, że ​​nie uważam tego za "czytelną". Ale teraz zajmie się tym, aby lepiej zrozumieć. – Harshdeep

3

Utkanos męska działa dobrze, ale moje doświadczenie jest to, że, gdy dokument XML jest duża, może to prowadzić do problemów z wydajnością.

W tym scenariuszu można po prostu przekazać pozycję rodzica w parametrze.

<xsl:template match="/"> 
<html> 
    <body> 
    <xsl:apply-templates/> 
    </body> 
    </html> 
</xsl:template> 

<xsl:template match="cd"> 
    <p> 
    <xsl:number format="1. "/><br/> 
    <xsl:apply-templates select="title"> 
     <xsl:with-param name="parent_position" select="position()"/> <!-- Send here --> 
    </xsl:apply-templates> 
    <xsl:apply-templates select="artist"/> 
    </p> 
</xsl:template> 

<xsl:template match="title"> 
    <xsl:param name="parent_position"/> <!-- Receive here --> 
    <xsl:number format="1" select="$parent_position"/><br/> 
    Title: <span style="color:#ff0000"> 
    <xsl:value-of select="."/></span> 
    <br /> 
</xsl:template> 

wynik:

<html xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><body> 
    <p>1. <br>1<br> 
    Title: <span style="color:#ff0000">Empire Burlesque</span><br>Bob Dylan</p> 
    <p>2. <br>1<br> 
    Title: <span style="color:#ff0000">Hide your heart</span><br>Bonnie Tyler</p> 
</body></html> 
Powiązane problemy