XSLT - apply a template to call-template result

后端 未结 1 601
无人共我
无人共我 2021-02-10 10:58

Is it possible to apply a template to the result of a call-template?

For example, the xml and 2 xslt below.

index.xml:



        
相关标签:
1条回答
  • 2021-02-10 12:00

    Is there any way to apply a template to the result of <xsl:call-template name="temp2" /> in index.xsl?

    Yes, this is called multi-pass processing. The only peculiarity is that in XSLT 1.0 you must apply the implementation-dependent xxx:node-set() extension function to any intermediate result, which in general will be of the infamous RTF (Result Tree Fragment) type and thus will need to be converted to a regular tree.

    Here is a complete example of multi-pass processing (I am using xsl:apply-templates and not xsl:call-template, but you can freely modify this example to use named templates and xsl:call-template instead):

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="/*">
      <xsl:variable name="vrtfPass1">
       <xsl:apply-templates select="num"/>
      </xsl:variable>
    
      <xsl:apply-templates mode="pass2"
        select="ext:node-set($vrtfPass1)/*"/>
     </xsl:template>
    
     <xsl:template match="num">
      <num><xsl:value-of select="2* ."/></num>
     </xsl:template>
    
     <xsl:template match="num" mode="pass2">
      <num><xsl:value-of select=". * ."/></num>
     </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 ( the content of any num elements is doubled in the first pass, then squared in the second pass) is produced:

    <num>4</num>
    <num>16</num>
    <num>36</num>
    <num>64</num>
    <num>100</num>
    <num>144</num>
    <num>196</num>
    <num>256</num>
    <num>324</num>
    <num>400</num>
    

    II. In XSLT 2.0

    The RTF "type" was abolished, so it is much more easier to specify multi-pass processing, which becomes almost indistinguishable from functional composition, as the following equivalent transformation shows:

    <xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:my="my:my" exclude-result-prefixes="my">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="/*">
      <xsl:sequence select="my:squareAll(my:doubleAll(*))"/>
     </xsl:template>
    
     <xsl:function name="my:doubleAll" as="element()*">
      <xsl:param name="pElems" as="element()*"/>
    
      <xsl:for-each select="$pElems">
       <xsl:copy>
        <xsl:sequence select=". + ."/>
       </xsl:copy>
      </xsl:for-each>
     </xsl:function>
    
     <xsl:function name="my:squareAll" as="element()*">
      <xsl:param name="pElems" as="element()*"/>
    
      <xsl:for-each select="$pElems">
       <xsl:copy>
        <xsl:sequence select=". * ."/>
       </xsl:copy>
      </xsl:for-each>
     </xsl:function>
    </xsl:stylesheet>
    

    when this transformation is applied on the same XML document (above), the same correct result is produced:

    <num>4</num>
    <num>16</num>
    <num>36</num>
    <num>64</num>
    <num>100</num>
    <num>144</num>
    <num>196</num>
    <num>256</num>
    <num>324</num>
    <num>400</num>
    
    0 讨论(0)
提交回复
热议问题