При необходимости этот шаблон может быть переопределен. К примеру, ссылка может выглядеть как
Visit <а href="#">www.xsltdev.ru</a>
Соответственно, шаблон будет иметь вид
<xsl:template match="home">
<xsl:text>Visit </xsl:text>
<a href="#">www.xsltdev.ru</a>
</xsl:template>
Можно заметить, что оба шаблона имеют общую часть, которая выводит гипертекстовую ссылку. Эта часть может быть вынесена во внешнее преобразование
home.xsl
.
Листинг 5.18. Преобразование home.xml
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="home">
<a href="#">www.xsltdev.ru</a>
</xsl:template>
</xsl:stylesheet>
Для того чтобы использовать внешний шаблон, основное преобразование должно импортировать его при помощи
xsl:import
и применять посредством xsl:apply-imports.
Листинг 5.19. Основное преобразование base.xsl
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:import href="#"/>
<xsl:template match="home">
<xsl:text>Visit </xsl:text>
<xsl:apply-imports/>
</xsl:template>
</xsl:stylesheet>
Элемент
xsl:apply-imports
нельзя использовать в блоках
xsl:for-each
и при вычислении глобальных переменных. Дело в том, что при обработке
xsl:apply-imports
процессор применяет импортируемые правила в соответствии с текущим шаблоном. Текущий шаблон — это то самое правило, которое процессор выполняет при обработке элемента
xsl:apply-templates
. При вычислении глобальных переменных и обработке блоков
xsl:for-each
текущее правило становится пустым, и, соответственно, вызов
xsl:apply-imports
вызовет ошибку.
Элемент
xsl:apply-imports
применяет шаблоны точно так же, как и элемент
xsl:apply-templates
, но при этом он имеет две особенности.
□ Шаблоны, определенные в основном преобразовании, применяться не будут, поскольку
xsl:apply-imports
применяет только импортированные правила.
□ Элемент
xsl:apply-imports
применяет только те правила, режим (
mode
) которых совпадает с режимом текущего шаблона.
В текущей версии XSLT
xsl:apply-imports
не может вызывать импортированные именованные шаблоны.
Для того чтобы лучше понять, зачем нужна такая сложная схема импорта, проведем аналогию с объектно-ориентированным программированием. Если рассматривать правила преобразований как методы классов, то импорт преобразований будет ни чем иным, как наследованием — все методы (шаблоны) класса-потомка (импортируемого преобразования) будут доступны в классе-наследнике (импортирующем преобразовании). При этом класс-наследник может переопределить методы класса потомка (шаблоны основного преобразования имеют порядок импорта старше, чем шаблоны импортированного преобразования). В этой схеме использование элемента
xsl:apply-imports
будет равносильно вызову метода родительского класса вместо переопределенного метода класса потомка.
Приведем пример Java-классов, которые будут аналогичны преобразованиям
, определяющий шаблонное правило, задает не более чем условия, при которых это правило должно выполняться. Конкретные же действия и инструкции, которые должны быть исполнены, определяются содержимым элемента
xsl:template
и составляют тело шаблона.
Пример
Тело следующего шаблона (выделенное полужирным шрифтом):
<xsl:template match="page">
<body>
<xsl:value-of select="."/>
</body>
Комментарии
<xsl:copy-of select="comment"/>
</xsl:template>
состоит из литерального элемента
body
, текстового узла и элемента
xsl:copy-of
. При выполнении этого шаблона элемент
body
будет выведен как есть (при этом содержимое его будет вычислено); текстовый узел будет скопирован в выходящее дерево; элемент
xsl:copy-of
будет заменен множеством дочерних комментариев текущего узла.
Следует заметить, что текстовый узел в данном случае состоит не только из строки "Комментарии". Он включает также все пробельные символы и символы переноса строки.
Тело шаблона может быть также и пустым. В этом случае результат обработки узлов, соответствующих этому шаблону будет пустым. Например, если в преобразовании содержится шаблон вида
<xsl:template match="comment"/>
то каждый раз, встретив узел комментария и обрабатывая его этим правилом, процессор будет получать пустой результат. Таким образом, используя пустые шаблоны совместно с идентичным преобразованием можно добиться эффекта удаления определенных узлов из шаблона, как это было показано ранее в этой главе.
Тело шаблона может содержать любые текстовые узлы, комментарии, инструкции по обработке и литеральные элементы результата при условии, что не будет нарушен синтаксис XML-документа. Тело шаблона может также содержать следующие элементы XSLT, называемые также инструкциями (не путать с инструкциями по обработке):