2009-10-25 14 views
6

Wiem, że czegoś tutaj brakuje. W poniższej transformacji XSLT rzeczywisty wynik nie pasuje do pożądanego wyniku.Jak zastosować szablony do każdego wybranego węzła w jednostce for?

Wewnątrz for-each, chcę zastosować szablon match="track" do każdego wybranego elementu track. Jeśli zrozumiałem XSLT poprawnie, z bieżącą konfiguracją tylko węzły podrzędne każdego wybranego elementu są dopasowane do szablonów, a nie same do siebie elementy track.

Jak ustawić elementy track przez szablon zgodnie z potrzebami? Czy muszę przemyśleć całe moje podejście?

Uwaga: Transformacja jest wykonywana przy użyciu PHP. Deklaracje XML zostały pominięte dla zwięzłości.

XML Document:

<album> 
    <title>Grave Dancers Union</title> 
    <track id="shove">Somebody To Shove</track> 
    <track id="gold">Black Gold</track> 
    <track id="train">Runaway Train</track> 
    <producer>Michael Beinhorn</producer> 
</album> 

XSL Stylesheet:

<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/album"> 
     <ol> 
      <xsl:for-each select="track"> 
       <li><xsl:apply-templates/></li> 
      </xsl:for-each> 
     </ol> 
    </xsl:template> 

    <xsl:template match="track"> 
     <a href="{@id}"><xsl:apply-templates/></a> 
    </xsl:template> 
</xsl:stylesheet> 

Wynik:

<ol> 
    <li>Somebody To Shove</li> 
    <li>Black Gold</li> 
    <li>Runaway Train</li> 
</ol> 

pożądany rezultat:

<ol> 
    <li><a href="shove">Somebody To Shove</a></li> 
    <li><a href="gold">Black Gold</a></li> 
    <li><a href="train">Runaway Train</a></li> 
</ol> 

Odpowiedz

9

Zgadzam się z "ndim", że prawdopodobnie należy zrestrukturyzować swój XSLT, aby zlikwidować pętlę xsl: for-each.

Alternatywnie, można zmienić xsl: apply-templates wybierz bieżący węzeł ścieżki wewnątrz xsl: for-each

<xsl:for-each select="track"> 
    <li> 
     <xsl:apply-templates select="." /> 
    </li> 
</xsl:for-each> 

Utrzymanie xsl: for-each byłoby przynajmniej pozwalają na sortuj utwory w innej kolejności, jeśli chcesz.

+0

Dobry połów na sortowanie. Sądzę, że to najlepsze rozwiązanie, ze względu na sortowanie. – ndim

+0

Mogłem przysiąc, że już to wypróbowałem, ale chyba nie. Tego właśnie szukałem! – Jakob

4

bym zrestrukturyzować to trochę (jeśli nie trzeba sortowania podejście for-each umożliwia):

<xsl:template match="/album"> 
    <ol> 
    <xsl:apply-templates select="track"/> 
    </ol> 
</xsl:template> 

<xsl:template match="track"> 
    <li><a href="{@id}"><xsl:apply-templates/></a></li> 
<xsl:template> 

To wygląda krótsze i bardziej na miejscu , MOIM ZDANIEM.

Chyba Twój

<xsl:for-each select="track"> 
     <li><xsl:apply-templates/></li> 
    </xsl:for-each> 

spacery przez wszystkich elementów torowych z for-each, a następnie stosuje zasady domyślne dla swoich potomków. Tak więc zawartość for-each ma ten sam węzeł kontekstu, co szablon match="track", a zatem szablon match="track" nigdy nie jest zgodny.

Jeśli naprawdę chcesz używać for-each w ten sposób, trzeba będzie zmienić jeden z następujących dwóch rzeczy w swoim podejściu:

  1. Dodaj atrybut name="track" do szablonu match="track", a następnie użyj <xsl:call-template/> od for-each (mój pomysł, i gorzej niż Tim C)
  2. Użyj rozwiązania Tim C przy użyciu <xsl:apply-templates select="."/>. Ma to tę zaletę, że unika nazywania i utrzymywania możliwości sortowania ścieżek.
+0

Rozwiązanie dotyczące restrukturyzacji wydaje się mniej modułowe, niż bym chciał (nie pozwala mi również na uwzględnienie ścieżek w '

' lub '' gdziekolwiek indziej na stronie/stronie, przynajmniej nie używając tego samego arkusza stylów), ale prawdopodobnie masz rację, ponieważ jest to najłagodniejsze rozwiązanie dla tego przykładu. – Jakob

+0

@Jakob Jestem świadomy, że to jest starożytny, ale chcę tylko zwrócić uwagę, że można użyć atrybutu 'mode', aby wybrać inny szablon dla tych samych węzłów. Podobnie jak '' i ' ...'. – janek37

0

myślę użyciu apply-templates i szablon trybów jest czystsze rozwiązanie:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 

    <xsl:template match="/"> 
    <body> 
     <xsl:apply-templates select="album" mode="ol" /> 
    </body> 
    </xsl:template> 

    <xsl:template match="album" mode="ol"> 
    <ol> 
     <xsl:apply-templates select="track" mode="li" /> 
    </ol> 
    </xsl:template> 

    <xsl:template match="track" mode="li"> 
    <li> 
     <xsl:apply-templates select="." /> 
    </li> 
    </xsl:template> 

    <xsl:template match="track"> 
    <a href="{@id}"> 
     <xsl:value-of select="." /> 
    </a> 
    </xsl:template> 


</xsl:stylesheet> 

skutkuje:

<body> 
    <ol> 
    <li> 
     <a href="shove">Somebody To Shove</a> 
    </li> 
    <li> 
     <a href="gold">Black Gold</a> 
    </li> 
    <li> 
     <a href="train">Runaway Train</a> 
    </li> 
    </ol> 
</body> 
0

Instrukcja for-each oświadczenie zmienia węzła kontekstowego z albumu utwór. Wywołanie polecenia apply templates powoduje zastosowanie szablonów do węzłów potomnych węzła kontekstu, które w danym przypadku są węzłami potomnymi elementu ścieżki. Stąd twój szablon, który pasuje do "śladu", nigdy nie zostanie trafiony.

Powiązane problemy