I don't know if it's possible, but I'm wondering how to do it...
Let's say we have the following XSL:
<xsl:template name="foo">
Bla bla bla
</xsl:template>
...
<xsl:template name="bar">
Bla bla bla
</xsl:template>
...
<xsl:template match="/">
<xsl:if test="$templateName='foo'">
<xsl:call-template name="foo"/>
</xsl:if>
<xsl:if test="$templateName='bar'">
<xsl:call-template name="bar"/>
</xsl:if>
</xsl:template>
Is it possible to change the XSL to read something like...
<xsl:template match="/">
<xsl:call-template name="$templateName"/>
</xsl:template>
For anyone's future reference:
Here is a working example based on Pavel Minaev's answer. No original thought on my part. ;-) I switched it to use msxml:node-set as he described (more or less) so that it works in .NET.
What about this one?:
You can simplify a "call" of the template using a variable similarly as described in an earlier contribution:
Note that optional
<xsl:with-param>
can be used as usual.Update: The links below were updated to point to web.archive.org -- unfortunately, IDEALLIANCE has made all Exteme Markup Languages conference proceedings unavailable... In due time, I will find a more permanent place for these two articles.
This is implemented in FXSL.
There are good explanations of the main principles of FXSL.
See the following two articles:
"Functional programming in XSLT using the FXSL library" (for XSLT 1.0), (PDF) at:
http://web.archive.org/web/20070710091236/http://www.idealliance.org/papers/extreme/proceedings/xslfo-pdf/2003/Novatchev01/EML2003Novatchev01.pdf
(HTML) at:
http://conferences.idealliance.org/extreme/html/2003/Novatchev01/EML2003Novatchev01.html
"Higher-Order Functional Programming with XSLT 2.0 and FXSL" (PDF) at:
http://web.archive.org/web/20070222111927/http://www.idealliance.org/papers/extreme/proceedings/xslfo-pdf/2006/Novatchev01/EML2006Novatchev01.pdf
(HTML) at: http://conferences.idealliance.org/extreme/html/2006/Novatchev01/EML2006Novatchev01.html
Using FXSL I have been able to solve easily and elegantly many problems, that seem "impossible for XSLT". One can find a lot of examples here.
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:
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 usenode-set()
to convert the resulting tree fragment to a plain node to match against, without the need fordocument('')
hack.For more information, see FXSL - it's a functional programming library for XSLT that is based on this concept.
I think I had more or less the same problem as you. I had an "outer" template and wanted to call a different "inner" template depending on some variable set at run-time. I found your question by Googling for a way to have a dynamic
<xsl:call-template>
. I solved it by using<xsl:apply-templates>
instead, as follows.The input XML (generated at run-time) contains something along the lines of:
The XSL in the "outer" template has:
(The
select="template"
in this apply-templates refers to the<template>
tag in the input XML)And finally the "inner" template, which I wanted to include as a result of the value of the
name
attribute in my XML, looks like:(Again, the
match="template[@name='xyz']"
refers to the previousselect="template"
and in turn to the<template>
tag and itsname
attribute in the input XML)In this way I can have a dynamically "called" template simply by controlled from my input XML.
This might not be the same problem as you are trying to solve but I think it's pretty close, and much simpler than the FSXL solutions mentioned elsewhere on this page.
No, this is
not possiblenot directly possible. The calling convention is:Where a QName is defined as:
Basically this boils down to "characters only, no expressions". As the other answers highlight, there are in fact ways to do something equivalent, but the straightforward approach/naïve approach will not work.