2011-09-17 8 views
8

Jak mogę uzyskać za pomocą XSLT, wartości węzła w pozycji X, bez użycia foreachKorzystanie XSLT uzyskać wartość węzła w pozycji X

<items> 
<item1>x</item1> 
<item2>x</item2> 
<item3>x</item3> 
</items> 

Jest to wyjaśnione w sensie programowania:

<xsl:value-of select="Items/Item[2]"/> 

== ================================================

Po prostu małe pytanie, w następującym xml:

<items> 
    <about>xyz</about> 
    <item1> 
     <title>t1</title> 
     <body>b1</body> 
    </item1> 
    <item2> 
     <title>t2</title> 
     <body>b2</body> 
    </item2> 
    <item3> 
     <title>3</title> 
     <body>3</body> 
    </item3> 
</items> 

Jak mogę wybrać tytuł drugiego przedmiotu.

+0

Dobre pytanie, +1. Zauważ, że większość odpowiedzi zawiera wyrażenia, które w zależności od dokumentu XML mogą potencjalnie wybrać "tytuł", który nie jest dzieckiem elementu macierzystego "element" XYZ. –

Odpowiedz

16

odpowiedź na pytanie rozszerzonym. Można użyć wartości pozycyjnej jeśli wybierzesz zestaw węzłów z poszukiwanych elementów:

<xsl:value-of select="(items//title)[2]"/> 

czyli

<xsl:value-of select="(items/*/title)[2]"/> 

Uwaga użycie nawiasu wymaganych do powrotu poszukiwany węzeł ustawiony przed wybraniem przez pozycja.


Możesz użyć tego, co nazywasz "w sensie programowania". Jednak trzeba * powodu nieznanej nazwy elementów dzieci:

<xsl:value-of select="items/*[2]"/> 

Zauważ, że węzły-zestawy w XSLT nie zera. W powyższy sposób wybierasz drugi element item, a nie trzeci .

Naprawdę trzeba position() kiedy chcesz porównać aktualną pozycję z numerem na przykład:

<xsl:value-of select="items/*[position()>2]"/> 

aby zaznaczyć cały element z pozycji tarce niż 2. innym przypadku position() jest indespensible jest, gdy wartość pozycji jest to zmienna typu ciąg:

<xsl:variable name="pos" select="'2'"/> 
<xsl:value-of select="items/*[position()=$pos]"/> 
+0

Odpowiedziałem na rozwinięte pytanie. Mam nadzieję, że to pomoże. –

+1

Bardzo mi to pomogło z podobnym problemem. Świetne, proste rozwiązanie, dzięki. –

2

można wykorzystywać pozycję()

<xsl:value-of select="/items/*[position()=2]/text()"/> 
2

Można to zrobić z

<xsl:value-of select="items/child[position()=2]"/> 
4

Wystarczy trochę poszerzyć pytanie w następujący xml:

<items> 
    <about>xyz</about> 
    <item1> 
     <title>t1</title> 
     <body>b1</body> 
    </item1> 
    <item2> 
     <title>t2</title> 
     <body>b2</body> 
    </item2> 
    <item3> 
     <title>3</title> 
     <body>3</body> 
    </item3> 
</items> 

Jak mogę wybrać sekunda tytuł artykuł.

Zastosowanie:

/*/*[starts-with(name(), 'item')][2]/title 

Wybiera: wszystkie title elementy, które są dzieci drugiego wszystkich dzieci-elementów górnego elementu, których nazwiska zaczynają się od ciągu "item".

Należy pamiętać, że wyrażenia takie jak:

(items/*/title)[2] 

lub

(items//title)[2] 

nie są prawidłowe w ogóle, bo jeśli w dokumencie XML są też inne elementy, takie jak (słownie) "chapter", które mają dzieci title, powyższe wyrażenia mogą wybrać element chapter/title - , ale Zadaniem tutaj jest wybranie drugiego title w dokumencie, którego elementem macierzystym mógłby być tylko element item XYZ.

+0

+1 dla bardziej ogólnego rozwiązania. Jednak wyrażenia w mojej odpowiedzi _jest poprawne_ w podanej próbie; mogą oczywiście działać źle, jeśli dokument wejściowy ulegnie zmianie. Może się to również zdarzyć z twoim wyrażonym wyrażeniem. –

+0

@empo: Dzięki, i tak, podczas gdy moje rozwiązanie jest bardziej ogólne i mocniejsze niż twoje, zawsze jest szansa, że ​​nawet bardziej radykalne zmiany mogą spowodować, że * dowolne * rozwiązanie będzie nieodpowiednie. Tak więc, zazwyczaj dbam o warianty, które są * całkiem możliwe *, ale * nie ekstremalne *. –

+0

Zgadzam się, ale muszę powiedzieć, że wyrażenia, których użyłem w mojej odpowiedzi, nie są prawidłowe_, to nie jest poprawne :). Możesz powiedzieć, że te wyrażenia są mniej niezawodne i mogą zawieść, jeśli zmienia się dokument wejściowy. –

Powiązane problemy