Search code examples
xsltnode-set

XSLT: apply a template to a tree fragment


I have defined a variable $NodeVariable, for instance:

<xsl:variable name="NodeVariable">
    <aT>
        <aT2>foo</aT2>
        <aT3>bar</aT3>
    </aT>
</xsl:variable>

and in different parts of the code I want to "apply" different templates to myVariable. Unfortunately, I don't know what's the syntax for this.

I've tried the following:

<xsl:for-each select="$NodeVariable"> 
    <xsl:call-template name="ns:ExtractInfo1"/>
</xsl:for-each>

<xsl:copy-of select="$NodeVariable"> 
    <xsl:call-template name="ns:ExtractInfo2"/>
</xsl:for-each>

<xsl:copy-of select="$NodeVariable"> 
    <xsl:call-template name="ns:ExtractInfo3"/>
</xsl:for-each>

which doesn't work.

How to apply a template to a tree fragment?


Solution

  • Assuming you use an XSLT 1.0 processor, you need to convert the result tree fragment to a node set first:

    <xsl:variable name="NodeVariable">
        <aT>
            <aT2>foo</aT2>
            <aT3>bar</aT3>
        </aT>
    </xsl:variable>
    
    <xsl:variable name="NodeSet" select="exsl:node-set($NodeVariable)"/>
    

    (where the stylesheet declares xmlns:exsl="http://exslt.org/common"), then you can apply-templates in different modes as needed e.g.

    <xsl:apply-templates select="$NodeSet/aT" mode="m1"/>
    

    and write templates for that mode e.g.

    <xsl:template match="aT" mode="m1">
      <xsl:value-of select="aT2"/>
    </xsl:template>
    

    Of course if you really want to call named templates you could do that as well, but using apply-templates and modes for different processing steps is the preferred way in XSLT in my view.