How to do a second transform on the output of an XSLT template

前端 未结 2 1290
醉梦人生
醉梦人生 2020-12-02 21:12

I have only basic XSLT skills so apologies if this is either basic or impossible.

I have a paginator template which is used everywhere on the site I\'m looking at. T

相关标签:
2条回答
  • 2020-12-02 21:50

    Here is a complete example how multi-pass processing can be done with 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>
    

    when this transformation is applied on the following XML document:

    <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>
    

    the wanted result (each num is multiplied by 2 and in the next pass 3 is added to each num) is produced:

    <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>
    
    0 讨论(0)
  • 2020-12-02 22:03

    It's possible in XSLT 2; you can store data in a variable and call apply-templates on that.

    Basic example:

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

    And somewhere in your stylesheet have a template that matches Elem. You can also use a separate mode to keep a clear distinction between the two phases (building the variable and processing it), especially when both phases use templates that match the same nodes.

    0 讨论(0)
提交回复
热议问题