Doing a double-pass in XSL?

后端 未结 2 954
忘了有多久
忘了有多久 2021-01-14 10:39

Is it possible to store the output of an XSL transformation in some sort of variable and then perform an additional transformation on the variable\'s contents? (All in one X

相关标签:
2条回答
  • 2021-01-14 10:55

    Yes, with XSLT 2.0 it is easy. With XSLT 1.0 you can of course also use modes and store a temporary result in a variable the same way as in XSLT 2.0 but the variable is then a result tree fragment, to be able to process it further with apply-templates you need to use an extension function like exsl:node-set on the variable.

    0 讨论(0)
  • 2021-01-14 11:02

    XSLT 2.0 Solution :

    <xsl:variable name="firstPassResult">
      <xsl:apply-templates select="/" mode="firstPass"/>
    </xsl:variable>
    
    <xsl:template match="/">
      <xsl:apply-templates select="$firstPassResult" mode="secondPass"/>
    </xsl:template>
    

    The trick here, is to use mode="firstPassResult" for the first pass while all the templates for the sedond pass should have mode="secondPass".

    Edit:

    Example :

    <root>
      <a>Init</a>
    </root>
    
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output indent="yes"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:variable name="firstPassResult">
        <xsl:apply-templates select="/" mode="firstPass"/>
      </xsl:variable>
    
      <xsl:template match="/" mode="firstPass">
          <test>
            <firstPass>
              <xsl:value-of select="root/a"/>
            </firstPass>
          </test>
      </xsl:template>
    
      <xsl:template match="/">
        <xsl:apply-templates select="$firstPassResult" mode="secondPass"/>
      </xsl:template>
    
      <xsl:template match="/" mode="secondPass">
        <xsl:message terminate="no">
          <xsl:copy-of select="."/>
        </xsl:message>
      </xsl:template>
    
    </xsl:stylesheet>
    

    Output :

    [xslt] <test><firstPass>Init</firstPass></test>
    

    So the first pass creates some elements with the content of root/a and the second one prints the created elements to std out. Hopefully this is enough to get you going.

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