комментариям, с ними по умолчанию не следует делать ничего, то есть узлы пространств имен просто удаляются.
Встроенные шаблоны имеют наименьший приоритет импорта, а значит, будут использоваться лишь тогда, когда в преобразовании нет другого, более подходящего правила. Иными словами, любой шаблон, определенный в преобразовании, будет иметь больший приоритет, чем у встроенных правил.
Такое положение вещей позволяет переопределять преобразования, применяемые к узлам документа по умолчанию. Например, во многих случаях бывает весьма полезным идентичное преобразование, которое копирует узлы как есть. Мы уже встречались с ним, когда создавали шаблон для генерации таблицы ссылок 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
Как можно заметить, в выходящем документе элементы а
и с
'пропали', но при этом их содержимое осталось нетронутым. Все дело во встроенных шаблонах, которые по умолчанию рекурсивно обрабатывают содержимое элементов и копируют текстовые узлы, если иного не определено.
Для того чтобы избежать подобного рода казусов, можно использовать идентичное преобразование, которое в случае отсутствия шаблонов для обработки тех или иных узлов копирует их в выходящий документ как есть. Идентичное преобразование записывается в следующем виде.
<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
, будет записано следующим образом.
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:import href='identity.xsl'/>
<xsl:template match='bold'>
<b>
<xsl:apply-templates/>
</b>
</xsl:template>
</xsl:stylesheet>
Результат будет иметь вид:
<a>
text a
<b>
text b
<b/>
</b>
<c>
text c
</c>
</a>
Другим примером использования идентичного преобразования может послужить случай, когда нужно