Книга: Технология XSLT

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

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

Наличие в 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, будет записано следующим образом.

Листинг 5.12

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

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

<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:import href="identity.xsl"/>
 <xsl:template match="comment()"/>
</xsl:stylesheet>

Оглавление книги


Генерация: 5.569. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз