XSLT: вызываем темплейт параметром

XSLT: вызываем темплейт параметром

Заголовок абсолютно не отражает того, о чем хочу написать. Хотелось впихнуть в него и ключевых слов, и смысла и чтобы место мало занимал. Не получилось. Речь пойдет о технике template tagging.

Общий смысл техники template tagging

В традиционном XSLT мы можем вызвать один шаблон из другого прямо ссылаясь на него по имени:

<xsl:template match="/">
<xsl:call-template name="hello"/>
</xsl:template>

 

<xsl:template name="hello">
<h1>Hello!</h1>
</xsl:template>

 

В большинстве случаев этого достаточно. Но возможность вызывать темплейт по имени, полученному динамически (скажем из исходного XML или путем вычисления) открывает весьма неплохие возможности «программирования на XSLT», как это смешно бы ни звучало.

Самый простой и бесполезный пример, что приходит в голову — передать в исходный XML название старницы, а на основании этого названия получить вызов требуемого шаблона, и соответственно — материалов требуемой страницы.

Дело в том, что невозможно выполнить такую конструкцию:

<xsl:call-template name="{/main/template1name}"/>

В элементе call-template нельзя использовать подстановку значения атрибута. Однако, это вполне годится для элемента apply-templates! Техника template tagging разрешает нашу задачу.

Вызов шаблона по имени: оснастка

Отрывок XSLT:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ra="http://revolverart.ru/">
<xsl:variable name="doc" select="/" />

...

<xsl:template name="caller">
<xsl:param name="n"/>
<xsl:apply-templates select="document('')//ra:templ[@name=$n]">
<xsl:with-param name="i" select="$i"/>
</xsl:apply-templates>
</xsl:template>

...

<xsl:template match="/">
<xsl:call-template name="caller">
<xsl:with-param name="n" select="/main/templatename"/>
</xsl:call-template>
</xsl:template>

...

<ra:templ name="hello" />
<xsl:template match="ra:templ[@name='hello']" >
<h1>Hello</h1>
</xsl:template>

...

</xsl:stylesheet>

 

Отрывок исходного XML:

<main>
<templatename>hello</templatename>
</main>

Что происходит при выполнении?

Имя шаблона, который мы хотим вызвать поступает из области данных (из XML). Область визуализации (XSLT) просто делает то, что мы от неё хотим. Вожделенное разделение представления и данных актуализируется.

Недостатки метода (php5 и libxml); как метод использовался в моих проектах.

Из того, что заметил сам. При использовании этой техники модуль XSL генерирует ошибки класса warning. В чем причина - пока не разобрался. Лечится подавлением ошибок. Проблем после этого не обнаружено.

Были проблемы при сочетании данной техники и техники динамически собираемых шаблонов XSLT-преобразования, упомянутой в статье о использовании XSLT. Суть этих проблем осталась для меня малопонятной по причине нехватки времени на изучение. Все решилось дополнительным перегоном только что испеченого XSLT (в виде DOMDocument) в текст (метод saveXML) и сразу же — обратно в DOMDocument (метод loadXML)

В основном я использовал данную технику для «разведения» управления преобразованием в пределах одного шаблона, примерно так, как описано в статье. В ситуации, когда один xslt обслуживает визуализацию одного раздела сайта со всем многообразием возможных вариантов этой самой визуализации...

Ссылки

Сам узнал о технике их книжки O'Reilly XSLT Cookbook. Там есть глава о Generic и Functional programming в XSLT и ссылка на сайт TopXML — сборник ресурсов о нетрадиционном подходе к применению XSL

 

Комментарии (2)

mem: 1073 total: 16 module: 8 xsl: 4