Включение документа в преобразование
Другой возможностью объединения документов и преобразований является включение элемента документа в преобразование в виде элемента верхнего уровня.
Поскольку преобразование также является XML-документом, доступ к данным, которые оно содержит можно получить при помощи функции document
, так же, как если бы документ преобразования был внешним документом. Функция document
, которой в качестве параметра была передана пустая строка, возвращает множество, состоящее из корневого узла самого преобразования. То есть, если документ был включен в преобразование в качестве элемента верхнего уровня с именем, к примеру, user:input
, получить доступ к нему можно при помощи выражения
document('')/xsl:stylesheet/user:input
<whatever/>
<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>
<output>
<A/>
<B/>
</output>
Следует обратить внимание на следующие особенности этого примера.
□ Элементы верхнего уровня в обязательном порядке должны иметь ненулевое пространство имен. Поэтому мы включили элемент input
и все его дочерние узлы в пространство имен urn:user
. В листинге 4.23 эти элементы выделены полужирным шрифтом.
□ В шаблонах, которые обрабатывают элементы включенного документа, должны указываться паттерны, соответствующие расширенным именам этих элементов, то есть не input
, a user:input
.
□ Чтобы не выводить объявления пространств имен в выходящем документе, мы включили префикс user
в атрибут exclude-result-prefixes
элемента xsl:stylesheet
.
Как можно видеть, включение элемента input
как элемента верхнего уровня породило определенные проблемы. Для того чтобы избежать их, можно воспользоваться маленьким фокусом — включать документ не
Результат следующего преобразования в точности совпадает с результатом преобразования в предыдущем примере.
<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>