Преобразование целиком будет иметь следующий вид.
Листинг 5.4. Преобразование, добавляющее перечень ссылок
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml">
Links found on this page:
Применив это преобразование, например, к главной странице Консорциума W3 ( http://www.w3.org), мы получим ее точный дубликат, в конце которого будет приведен перечень всех найденных текстовых ссылок. Выходящий документ будет заканчиваться фрагментом вида:
Links found on this page:
About W3C
Accessibility
Activities
и так далее.
Заметим, что того же эффекта можно было добиться другими способами, например, при помощи именованных шаблонов или элемента xsl:for-each, однако применение режимов, пожалуй, является наиболее гибкой техникой.
Досадным ограничением режимов является то, что режим нельзя выбирать динамически. Атрибут modeобязан иметь фиксированное значение, то есть вызов вида:
будет некорректным. Особо серьезных практических противопоказаний для динамических режимов нет, будем надеяться, что в следующих версиях XSLT они появятся.
Вместо того чтобы при помощи атрибута matchуказывать, какая часть входящего документа должна преобразовываться данным шаблоном, ему можно присвоить имя и вызывать в любой момент вне зависимости от контекста преобразования. Такие шаблоны очень схожи по принципу с процедурами в императивных языках программирования — они позволяют выносить часто используемые части преобразований, передавать им параметры и вызывать вне зависимости от того, что именно обрабатывается в данный момент.
Имя шаблонному правилу присваивается атрибутом name элемента xsl:template. После этого шаблону более необязательно иметь атрибут match, теперь он может быть вызван просто по имени. Два шаблона с одним порядком импорта не могут иметь одинаковых имен. Если же одинаковые имена имеют шаблоны различного порядка импорта, шаблоны старшего порядка переопределяют младшие шаблоны
Пример
При генерации HTML-страниц часто встречающейся задачей является создание элемента head. Элемент head, как правило, содержит несколько элементов meta, предоставляющих метаинформацию, элемент title, который определяет название страницы и элемент link, который связывает данную страницу с другими документами, например, с каскадными таблицами стилей (CSS).
Для того чтобы упростить процедуру генерации head, мы можем вынести ее в отдельный именованный шаблон.
Листинг 5.5. Именованный шаблон для генерации элемента head
content="This site is dedicated to XSLT and Xpath."/>
Думается, этот шаблон не требует пояснений — он просто создает в входящем документе несколько элементов. Непонятным пока остается другое — как вызывать именованные шаблоны? Элемент xsl:apply-templatesявно не подходит, поскольку именованные шаблоны не обязаны иметь атрибут match. Их выполнение производится элементом xsl:call-template.
Элемент xsl:call-template
Приведем синтаксис этого элемента:
name=" имя ">
Обязательный атрибут name указывает имя шаблона, который вызывается этой инструкцией. Например, шаблон с именем " head", приведенный выше, может быть вызван следующим образом:
Атрибут nameпри вызове обязан иметь фиксированное значение — точно так же, как и в случае с modeи xsl:apply-templates, динамика здесь не разрешена.
При вызове xsl:call-templateне изменяет контекста преобразования. Фактически, вызов именованного шаблона эквивалентен замене в тексте преобразования элемента xsl:call-templateна тело вызываемого шаблона.
Приведем пример.
Листинг 5.6. Входящий документ
Just a few words...
Листинг 5.7. Преобразование
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
content="This site is dedicated to XSLT and Xpath."/>
Листинг 5.8. Выходящий документ
content="This site is dedicated to XSLT and Xpath.">
Just a few words...
Примечание
Несколько более эффективным способом использования в документе статических частей (как содержимое элемента headв приведенном примере) является хранение этих частей во внешних документах и вставка их в выходящий документ при помощи элемента xsl:copy-ofи функции document.
Читать дальше