It's not possible exactly as you describe, but if you want to be able to choose a template at run-time based on some value you set elsewhere, there is a trick to do that. The idea is to have your named template also match a node with a corresponding name in a distinct mode (so that it doesn't mess up your normal transformation), and then match on that. For example:
<xsl:stylesheet ... xmlns:t="urn:templates">
<!-- Any compliant XSLT processor must allow and ignore any elements
not from XSLT namespace that are immediate children of root element -->
<t:templates>
<t:foo/>
<t:bar/>
</t:templates>
<!-- document('') is the executing XSLT stylesheet -->
<xsl:variable name="templates" select="document('')//t:templates" />
<xsl:template name="foo" match="t:foo" mode="call-template">
Bla bla bla
</xsl:template>
<xsl:template name="bar" match="t:foo" mode="call-template">
Bla bla bla
</xsl:template>
<xsl:template match="/">
<xsl:variable name="template-name" select="..." />
<xsl:apply-templates select="$templates/t:*[local-name() = $template-name]"
mode="call-template"/>
</xsl:template>
Note that you can use <xsl:with-param>
in <xsl:apply-templates>
, so you can do everything with this that you could do with a plain <xsl:call-template>
.
Also, the code above is somewhat lengthier than you might need because it tries to avoid using any XSLT extensions. If your processor supports exslt:node-set()
, then you can just generate nodes directly using <xsl:element>
, and use node-set()
to convert the resulting tree fragment to a plain node to match against, without the need for document('')
hack.
For more information, see FXSL - it's a functional programming library for XSLT that is based on this concept.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…