Search code examples
xsltfxsl

How to call named templates based on a variable?


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>

Solution

  • No, this is not possible not directly possible. The calling convention is:

    <xsl:call-template name="QName" />
    

    Where a QName is defined as:

    QName ::= PrefixedName | UnprefixedName
    
    PrefixedName   ::= Prefix ':' LocalPart
    UnprefixedName ::= LocalPart
    
    Prefix         ::= NCName
    LocalPart      ::= NCName
    

    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.