2011-10-03 7 views
13

Mam tylko podstawowe umiejętności XSLT, więc przepraszam, jeśli jest to albo podstawowe, albo niemożliwe.Jak wykonać drugą transformację na wyjściu szablonu XSLT

Mam szablon paginatora, który jest używany wszędzie na stronie, na którą patrzę. Występuje błąd, w którym jedno konkretne wyszukiwanie musi mieć parametr categoryId dołączony do href linku do strony. Nie mogę zmienić arkusza stylów paginatora, inaczej po prostu dodałbym do niego parametr. Chciałbym zastosować szablon, a następnie wykonać drugą transformację na podstawie jej wyników. czy to możliwe? W jaki sposób inni zwykle korzystają z rozszerzania szablonów bibliotecznych?

Do tej pory zastanawiałem się nad wykonaniem rekurencyjnej kopii danych wyjściowych i zastosowaniem szablonu do hrefów podczas ich przetwarzania. Składnia tego mi ucieka, szczególnie, że nie jestem nawet pewien, czy to możliwe.


Edytuj - Pomiędzy odpowiedzią Dabblera i komentarzem Michaela Kaya, dotarliśmy na miejsce. Oto mój pełny test.

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common"> 
    <!-- note we require the extensions for this transform --> 

    <!--We call the template to be extended here and store the result in a variable--> 
    <xsl:variable name="output1"> 
      <xsl:call-template name="pass1"/> 
    </xsl:variable> 

    <!--The template to be extended--> 
    <xsl:template name="pass1"> 
      <a href="url?param1=junk">foo</a> 
    </xsl:template> 

    <!--the second pass. we lock this down to a mode so we can control when it is applied--> 
    <xsl:template match="a" mode="pass2"> 
      <xsl:variable name="href" select="concat(@href, '&amp;', 'catid', '=', 'stuff')"/> 
      <a href="{$href}"><xsl:value-of select="."/></a> 
    </xsl:template> 

    <xsl:template match="/"> 
      <html><head></head><body> 
        <!--the node-set extension function turns the first pass back into a node set--> 
        <xsl:apply-templates select="ext:node-set($output1)" mode="pass2"/> 
      </body></html> 
    </xsl:template> 

</xsl:stylesheet> 

Odpowiedz

8

Jest to możliwe w XSLT 2; możesz przechowywać dane w zmiennej i wywoływać na nich szablony stosowania.

Podstawowe przykład:

<xsl:variable name="MyVar"> 
    <xsl:element name="Elem"/> <!-- Or anything that creates some output --> 
</xsl:variable> 
<xsl:apply-templates select="$MyVar"/> 

A gdzieś w swoim arkuszu stylów mieć szablon, który pasuje Elem. Możesz także użyć oddzielnego trybu, aby zachować wyraźne rozróżnienie między dwiema fazami (budując zmienną i przetwarzając ją), szczególnie gdy obie fazy używają szablonów pasujących do tych samych węzłów.

+5

I można zrobić to samo w XSLT 1.0 z dowolnym procesorem, który oferuje exsl: node-set() Rozszerzenie: wystarczy wymienić wybierz w apply-templates z select = "exsl: node-set ($ MyVar)". –

15

Powyżej znajduje się pełna przykładów, jak przetwarzania wielo-pass można zrobić z XSLT 1.0:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

    <xsl:template match="node()|@*" mode="mPass2"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*" mode="mPass2"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/"> 
    <xsl:variable name="vrtfPass1Result"> 
    <xsl:apply-templates/> 
    </xsl:variable> 

    <xsl:apply-templates mode="mPass2" 
     select="ext:node-set($vrtfPass1Result)/*"/> 
</xsl:template> 

<xsl:template match="num/text()"> 
    <xsl:value-of select="2*."/> 
</xsl:template> 

<xsl:template match="/*" mode="mPass2"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates mode="mPass2"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="num/text()" mode="mPass2"> 
    <xsl:value-of select="3 + ."/> 
</xsl:template> 
</xsl:stylesheet> 

kiedy ta transformacja jest stosowane na poniższym dokumencie XML:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

pożądany wynik (każdy num jest mnożony przez 2, aw następnym przebiegu 3 jest dodawany do każdego num) jest produkowany:

<nums> 
    <num>5</num> 
    <num>7</num> 
    <num>9</num> 
    <num>11</num> 
    <num>13</num> 
    <num>15</num> 
    <num>17</num> 
    <num>19</num> 
    <num>21</num> 
    <num>23</num> 
</nums> 
Powiązane problemy