<xsl:apply-templates

   select='.//xhtml:a[@href and not(xhtml:*)]'>

  <xsl:sort select='.'/>

 </xsl:apply-templates>

 </xsl:copy>

</xsl:template>

Если мы попытаемся выполнить преобразование, состоящее из этих шаблонов, мы обнаружим, что в тексте самого документа ссылки испортились — там тоже добавились элементы br и переносы строк. Это произошло потому, что шаблон для обработки ссылок имеет больший приоритет, чем шаблон, копирующий содержимое документа.

Для исправления этой ошибки мы выделим шаблон обработки ссылок в отдельный режим links:

<xsl:template match='xhtml:a' mode='links'>

 ...

</xsl:template>

Теперь это правило не будет применяться к ссылкам во время копирования содержимого документа, потому что при выполнении инструкции

<xsl:apply-templates select='@*|node()'/>

режим будет пустым, значит шаблон для xhtml:а вызываться не будет. Для того чтобы применить его при помощи xsl:apply-templates, мы добавим в этот элемент атрибут mode:

<xsl:apply-templates

 select='.//xhtml:a[@href and not(xhtml:*)]'

 mode='links'>

 <xsl:sort select='.'/>

</xsl:apply-templates>

Разберем более подробно это определение. Данная инструкция будет применять шаблоны с режимом links к узлам, возвращаемым выражением './/xhtml:a[@href and not (xhtml:*)]', отсортированным в алфавитном порядке своих строковых значений. Выражение './/xhtml:a[@href and not(xhtml:*)]' возвращает всех потомков текущего узла (путь выборки './/'), которые принадлежат пространству имен xhtml, являются элементами с именами а, (тест имени 'xhtml:a'), при этом имеют атрибут href и не включают в себя другие элементы (предикат '[@href and not (xhtml:*)] ').

Преобразование целиком будет иметь следующий вид.

Листинг 5.4. Преобразование, добавляющее перечень ссылок

<xsl:stylesheet

 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'>

 <xsl:template match='xhtml:body'>

  <xsl:copy>

   <xsl:apply-templates select='@*|node()'/>

   <h1>Links found on this page:</h1>

   <xsl:apply-templates select='.//xhtml:a[@href and not (xhtml:*)]'>

    <xsl:sort select='.'/>

   </xsl:apply-templates>

  </xsl:copy>

 </xsl:template>

 <xsl:template match='@*|node()'>

  <xsl:copy>

   <xsl:apply-templates select='@*|node()'/>

  </xsl:copy>

 </xsl:template>

 <xsl:template match='xhtml:a'>

  <xsl:copy>

   <xsl:copy-of select='@href|text()'/>

  </xsl:copy>

  <br/>

  <xsl:text>&#xA;</xsl:text>

 </xsl:template>

</xsl:stylesheet>

Применив это преобразование, например, к главной странице Консорциума W3 (http://www.w3.org), мы получим ее точный дубликат, в конце которого будет приведен перечень всех найденных текстовых ссылок. Выходящий документ будет заканчиваться фрагментом вида:

<h1>Links found on this page:</h1>

<a href='Consortium/'>About W3C</a><br/>

<a href='WAI/'>Accessibility</a><br/>

<a href='Consortium/Activities'>Activities</a><br/>

и так далее.

Заметим, что того же эффекта можно было добиться другими способами, например, при помощи именованных шаблонов или элемента xsl:for-each, однако применение режимов, пожалуй, является наиболее гибкой техникой.

Досадным ограничением режимов является то, что режим нельзя выбирать динамически. Атрибут mode обязан иметь фиксированное значение, то есть вызов вида:

<xsl:apply-templates mode='{$mode}'/>

будет некорректным. Особо серьезных практических противопоказаний для динамических режимов нет, будем надеяться, что в следующих версиях XSLT они появятся.

Именованные шаблоны

Вместо того чтобы при помощи атрибута match указывать, какая часть входящего документа должна преобразовываться данным шаблоном, ему можно присвоить имя и вызывать в любой момент вне зависимости от контекста преобразования. Такие шаблоны очень схожи по принципу с процедурами в императивных языках программирования — они позволяют выносить часто используемые части преобразований, передавать им параметры и вызывать вне зависимости от того, что именно обрабатывается в данный момент.

Имя шаблонному правилу присваивается атрибутом name элемента xsl:template. После этого шаблону более необязательно иметь атрибут match, теперь он может быть вызван просто по имени. Два шаблона с одним порядком импорта не могут иметь одинаковых имен. Если же одинаковые имена имеют шаблоны различного порядка импорта, шаблоны старшего порядка

Вы читаете Технология XSLT
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату