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

Включение документа в преобразование

Включение документа в преобразование

Другой возможностью объединения документов и преобразований является включение элемента документа в преобразование в виде элемента верхнего уровня.

Поскольку преобразование также является XML-документом, доступ к данным, которые оно содержит можно получить при помощи функции document, так же, как если бы документ преобразования был внешним документом. Функция document, которой в качестве параметра была передана пустая строка, возвращает множество, состоящее из корневого узла самого преобразования. То есть, если документ был включен в преобразование в качестве элемента верхнего уровня с именем, к примеру, user:input, получить доступ к нему можно при помощи выражения

document('')/xsl:stylesheet/user:input

Пример

Листинг 4.22. Входящий документ

<whatever/>

Листинг 4.23. Преобразование

<xsl:stylesheet
 version="1.0"
 xmlns:user="urn:user"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 exclude-result-prefixes="user">
 <input xmlns="urn:user">
  <a/>
  <b/>
 </input>
 <xsl:template match="/">
  <xsl:apply-templates
   select="document('')/xsl:stylesheet/user:input"/>
  </xsl:template>
 <xsl:template match="user:a">
  <A/>
 </xsl:template>
 <xsl:template match="user:b">
  <B/>
 </xsl:template>
 <xsl:template match="user:input">
  <output>
   <xsl:apply-templates/>
  </output>
 </xsl:template>
</xsl:stylesheet>

Листинг 4.24. Выходящий документ

<output>
 <A/>
 <B/>
</output>

Следует обратить внимание на следующие особенности этого примера.

? Элементы верхнего уровня в обязательном порядке должны иметь ненулевое пространство имен. Поэтому мы включили элемент input и все его дочерние узлы в пространство имен urn:user. В листинге 4.23 эти элементы выделены полужирным шрифтом.

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

? Чтобы не выводить объявления пространств имен в выходящем документе, мы включили префикс user в атрибут exclude-result-prefixes элемента xsl:stylesheet.

Как можно видеть, включение элемента input как элемента верхнего уровня породило определенные проблемы. Для того чтобы избежать их, можно воспользоваться маленьким фокусом — включать документ не как элемент верхнего уровня, а в элемент верхнего уровня.

Пример

Результат следующего преобразования в точности совпадает с результатом преобразования в предыдущем примере.

Листинг 4.25. Пользовательские данные в элементе верхнего уровня

<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template name="input">
  <input>
   <a/>
   <b/>
  </input>
 </xsl:template>
 <xsl:template match="/">
  <xsl:apply-templates
   select="document('')/
   xsl:stylesheet/xsl:template[@name='input']/input"/>
 </xsl:template>
 <xsl:template match="a">
  <A/>
 </xsl:template>
 <xsl:template match="b">
  <B/>
 </xsl:template>
 <xsl:template match="input">
  <output>
   <xsl:apply-templates/>
  </output>
 </xsl:template>
</xsl:stylesheet>

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

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

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


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