I want to pass the template name TemplateName as a parameter and it is possible to apply the corresponding template to the data.
In both XSLT 1.0 and XSLT 2.0, it is illegal to have a design such as:
<xsl:call-template name="{$vTemplateName}"/>
While XPath 3.0 (XSLT 3.0) introduces function elements and HOFs (higher order functions), HOFs can be emulated in previous versions of XSLT. Read the articles on the FXSL homepage for more information.
Here is a simplified example of the idea behind FXSL :
<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>
Given this XML sample, we have two templates: one that produces the sum of all num
elements, and the other creates their concatenation. We want to pass the desired operation as a parameter.
Here's how to do it (note that nothing in the source XML file tells us which operation to use):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:param name="pOp" select="'sum'"/> <my:ops> <op>sum</op> <op>concat</op> </my:ops> <xsl:variable name="vOps" select= "document('')/*/my:ops/*"/> <xsl:template match="/"> <xsl:apply-templates select="$vOps[. = $pOp]"> <xsl:with-param name="arg1" select="/*/*"/> </xsl:apply-templates> </xsl:template> <xsl:template match="op[.='sum']"> <xsl:param name="arg1"/> <xsl:value-of select="sum($arg1)"/> </xsl:template> <xsl:template match="op[.='concat']"> <xsl:param name="arg1"/> <xsl:for-each select="$arg1"> <xsl:value-of select="."/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
When applied to the XML document above, the desired, correct result is output:
55
when replacing :
<xsl:param name="pOp" select="'sum'"/>
from
<xsl:param name="pOp" select="'concat'"/>
and apply a new transformation, again you get the desired, correct result :
01020304050607080910
Please note :
The main (used) template can and usually will be in a separate XSLT style file and will import style sheets with templates that implement the operations. The main template does not know what operations are performed (and does not use <xsl:choose>
with hardcoded names).
In fact, if templates are added or deleted from imported files, there is no need to change the main (used) template. In this programming style, the <xsl:apply-templates>
command often selects execution templates that were not yet written when the main template was created.