Я хочу передать имя шаблона
TemplateName в качестве параметра и будет
возможность применить соответствующий шаблон на
данные.
В XSLT 1.0 и XSLT 2.0 запрещено иметь такую конструкцию, как:
<xsl:call-template name="{$vTemplateName}"/>
Хотя в XPath 3.0 (XSLT 3.0) представлены функциональные элементы и HOF (функции высшего порядка), HOF можно эмулировать в предыдущих версиях XSLT. Для получения дополнительной информации прочитайте статьи на главной странице FXSL .
Вот упрощенный пример идеи, лежащей в основе 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>
Учитывая этот пример XML, у нас есть два шаблона, один из которых выдает сумму всех элементов num
, а другой производит их конкатенацию. Мы хотим передать желаемую операцию в качестве параметра.
Вот как это сделать (обратите внимание, что в самом исходном XML ничего не говорит нам, какую операцию использовать):
<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>
При применении к XML-документу выше, желаемый, правильный результат получается:
55
при замене :
<xsl:param name="pOp" select="'sum'"/>
с
<xsl:param name="pOp" select="'concat'"/>
и примените новое преобразование, снова будет получен нужный, правильный результат :
01020304050607080910
Обратите внимание :
Основной (использующий) шаблон может и обычно находится в отдельном файле таблицы стилей XSLT и будет импортировать таблицы стилей с шаблонами, которые реализуют операции. Основной шаблон не знает, какие операции реализованы (и не использует <xsl:choose>
с жестко закодированными именами).
Фактически, если шаблоны добавляются или удаляются из импортированных файлов, нет необходимости изменять основной (используя) шаблон. В этом стиле программирования команда <xsl:apply-templates>
часто выбирает для шаблонов выполнения, которые еще не были написаны, когда был создан основной шаблон.