Чтение онлайн

ЖАНРЫ

Технология XSLT

Валиков Алексей Н.

Шрифт:

□ При использовании

xsl:apply-templates
процессор игнорирует значения атрибутов
name
элементов
xsl:template
; точно так же
xsl:call-template
принимает во внимание только значение атрибута
name
, игнорируя атрибуты
match
,
mode
и
priority
.

При желании можно найти еще с десяток отличий, но и этих положений вполне достаточно для того, чтобы понять разницу. Главным выводом из этого сравнения является то, что

xsl:apply-templates
демонстрирует декларативный, а
xsl:call-template
процедурный стиль программирования В первом случае мы используем объявленные (или задекларированные) правила преобразования, во втором — используем шаблон просто как процедуру.

Встроенные шаблоны

Для того чтобы обеспечить рекурсивную обработку документа при преобразовании, в XSLT существуют так называемые встроенные шаблоны. Несмотря на то, что они не описываются в преобразованиях явным образом, встроенные шаблоны применяются процессорами по умолчанию в случаях, когда более подходящих шаблонов нет.

Существуют пять основных шаблонных правил, которые применяются процессорами по умолчанию.

Первое из них обеспечивает рекурсивную обработку дочерних элементов документа, которые находятся как в корне, так и в других элементах. Это правило эквивалентно следующему шаблону:

<xsl:template match="*|/">

 <xsl:apply-templates/>

</xsl:template>

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

<xsl:template match="*|/" mode="режим">

 <xsl:apply-templates mode="режим"/>

</xsl:template>

В XSLT также определяется встроенное правило для обработки текстовых узлов и атрибутов — это правило просто выводит их текстовые значения. Шаблон такого преобразования может быть записан в виде:

<xsl:template match="text|@*">

 <xsl:value-of select="."/>

</xsl:template>

Четвертое правило касается обработки инструкций по обработке и комментариев. Это правило не делает ничего, то есть инструкции и комментарии просто опускаются в выходящем документе. Шаблон такого преобразования будет иметь вид

<xsl:template match="processing-instruction|comment"/>

Последнее, пятое правило определяет обработку узлов пространств имен. Аналогично инструкциям и комментариям, с ними по умолчанию не следует делать ничего, то есть узлы пространств имен просто удаляются.

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

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

Идентичное преобразование

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

bold
в элементы с именами
b
. Однако результатом обработки документа

<а>

 text a

 <bold>

text b

<bold/>

 </bold>

 <c>

text c

 </c>

</a>

преобразованием

<xsl:stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="bold">

<b><xsl:apply-templates/></b>

 </xsl:template>

</xsl:stylesheet>

будет документ вида

text a

<b>

 text b

 <b/>

</b>

text c

Как можно заметить, в выходящем документе элементы

а
и
с
"пропали", но при этом их содержимое осталось нетронутым. Все дело во встроенных шаблонах, которые по умолчанию рекурсивно обрабатывают содержимое элементов и копируют текстовые узлы, если иного не определено.

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

Листинг 5.11. Идентичное преобразование

<xsl:stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="@*|node">

<xsl:copy>

<xsl:apply-templates select="@*|node"/>

</xsl:copy>

 </xsl:template>

</xsl:stylesheet>

Единственный шаблон этого преобразования при помощи элемента

xsl:copy
рекурсивно создает в выходящем документе копии узлов и атрибутов. На практике идентичное преобразование используется очень часто, и потому мы настоятельно рекомендуем сохранить его в отдельном файле и импортировать при потребности.

Поясним, что это преобразование выполняет не просто копирование документа (для этого было бы достаточно элемента

xsl:copy-of
). Идентичное преобразование переопределяет встроенные шаблоны; теперь, если для обработки какого-либо узла в преобразовании не определено подходящего шаблона, он вместе со всеми своими потомками будет скопирован в выходящий документ без изменений.

Идентичное преобразование очень полезно в тех случаях, когда требуется изменить только некоторые части документа, оставив остальное в неприкосновенности. Например, в предыдущем примере нам нужно было только переименовать все документы

bold
. Искомое преобразование, импортирующее идентичное преобразование из файла
identity.xsl
, будет записано следующим образом.

Поделиться с друзьями: