это преобразование, например, к главной странице Консорциума W3 (http://www.w3.org), мы получим ее точный дубликат, в конце которого будет приведен перечень всех найденных текстовых ссылок. Выходящий документ будет заканчиваться фрагментом вида:
<h1>Links found on this page:</h1>
<a href="#">About W3C</a><br/>
<a href="#">Accessibility</a><br/>
<a href="#">Activities</a><br/>
и так далее.
Заметим, что того же эффекта можно было добиться другими способами, например, при помощи именованных шаблонов или элемента
xsl:for-each
, однако применение режимов, пожалуй, является наиболее гибкой техникой.
Досадным ограничением режимов является то, что режим нельзя выбирать динамически. Атрибут
mode
обязан иметь фиксированное значение, то есть вызов вида:
<xsl:apply-templates mode="{$mode}"/>
будет некорректным. Особо серьезных практических противопоказаний для динамических режимов нет, будем надеяться, что в следующих версиях XSLT они появятся.
Именованные шаблоны
Вместо того чтобы при помощи атрибута
match
указывать, какая часть входящего документа должна преобразовываться данным шаблоном, ему можно присвоить имя и вызывать в любой момент вне зависимости от контекста преобразования. Такие шаблоны очень схожи по принципу с процедурами в императивных языках программирования — они позволяют выносить часто используемые части преобразований, передавать им параметры и вызывать вне зависимости от того, что именно обрабатывается в данный момент.
Имя шаблонному правилу присваивается атрибутом name элемента
xsl:template
. После этого шаблону более необязательно иметь атрибут
match
, теперь он может быть вызван просто по имени. Два шаблона с одним порядком импорта не могут иметь одинаковых имен. Если же одинаковые имена имеют шаблоны различного порядка импорта, шаблоны старшего порядка переопределяют младшие шаблоны
Пример
При генерации HTML-страниц часто встречающейся задачей является создание элемента
head
. Элемент
head
, как правило, содержит несколько элементов
meta
, предоставляющих метаинформацию, элемент
title
, который определяет название страницы и элемент
link
, который связывает данную страницу с другими документами, например, с каскадными таблицами
стилей (CSS).
Для того чтобы упростить процедуру генерации
head
, мы можем вынести ее в отдельный именованный шаблон.
Листинг 5.5. Именованный шаблон для генерации элемента head
Думается, этот шаблон не требует пояснений — он просто создает в входящем документе несколько элементов. Непонятным пока остается другое — как вызывать именованные шаблоны? Элемент
xsl:apply-templates
явно не подходит, поскольку именованные шаблоны не обязаны иметь атрибут
match
. Их выполнение производится элементом
xsl:call-template
.
Элемент xsl:call-template
Приведем синтаксис этого элемента:
<xsl:call-template
name="имя">
<!-- Содержимое: несколько элементов xsl:with-param -->
</xsl:call-template>
Обязательный атрибут name указывает имя шаблона, который вызывается этой инструкцией. Например, шаблон с именем "
head
", приведенный выше, может быть вызван следующим образом:
<xsl:call-template name="head"/>
Атрибут
name
при вызове обязан иметь фиксированное значение — точно так же, как и в случае с
mode
и
xsl:apply-templates
, динамика здесь не разрешена.
При вызове
xsl:call-template
не изменяет контекста преобразования. Фактически, вызов именованного шаблона эквивалентен замене в тексте преобразования элемента