Q:

XSLT choose template

I have an application written in C# that needs to apply a template name to an xml file that is defined in an XSLT.
Example XML:
<Data>
    <Person>
        <Name>bob</Name>
        <Age>43</Age>
    </Person>
    <Thing>
       <Color>Red</Color>
    </Thing>
</Data>

Example XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:param name="TargetName" />
    <xsl:param name="RootPath" />

    <xsl:Template Name="AgeGrabber">
        <xsl:value-of select="/Person/Age" />
    </xsl:Template>

    <xsl:Template Name="ColorGrabber">
        <xsl:value-of select="/Color" />
    </xsl:Template>

</xsl:stylesheet>

Say I wanted to run the template "ColorGrabber" with path "/Data/Thing" and then run another transform with the template "AgeGrabber" with path "/Data". Is this possible? I was thinking I could pass in the path and the template name (hense the 2 params at the top) and then do some type of switch but it looks like xsl:call-template can not take a parameter as the name attribute.
How can I achieve this behaviour?

A:

There are a number of issues with this question:

<xsl:stylesheet version="2.0"  ... is specified, however, at present >NET doesn't natively support XSLT 2.0.
Thecode example is not too meaningful, because a single XML document cannot contain both /Person/Age and /Color elements -- a wellformed XML document has only a single top element and it can be either Person or Color, but not both.

In case there was a more meaningful example:
<Person>
 <Age>27</Age>
 <HairColor>blond</HairColor>
</Person>

one simple solution is:
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:param name="pProperty" select="'Age'"/>

 <xsl:template match="/">
  <xsl:value-of select="/*/*[name()=$pProperty]"/>
 </xsl:template>
</xsl:stylesheet>

and when this transformation is applied on the above XML document, it produces the wanted result:
27

In case the nestedness of the elements of interest can be arbitrary and/or we need to do different processing on the different elements, then an appropriate solution is to use matching templates (not named ones):
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pProperty" select="'HairColor'"/>

 <xsl:template match="Age">
  <xsl:if test="$pProperty = 'Age'">
    This person is <xsl:value-of select="."/> old.
  </xsl:if>
 </xsl:template>

 <xsl:template match="HairColor">
  <xsl:if test="$pProperty = 'HairColor'">
    This person has <xsl:value-of select="."/> hair.
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the same XML document (above), again the correct result is produced:
This person has blond hair.

Finally,  if you really want to simulate higher-order functions (HOF) in XSLT 1.0 or XSLT 2.0, see this answer: https://stackoverflow.com/a/8363249/36305 , or learn about FXSL.

