Корневой элемент преобразования xsl:stylesheet
может быть включен в преобразуемый документ со всеми дочерними элементами верхнего уровня и так далее. Для того чтобы использовать это преобразование, псевдоатрибут href
инструкции по обработке xml-stylesheet
должен указывать на идентификатор элемента xsl:stylesheet
, определенный в его атрибуте id
.
Пример
Листинг 4.20. Входящий документ
Main content
id="transform"
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Листинг 4.21. Выходящий документ
Main content
Поскольку элемент xsl:stylesheet
включен в преобразуемый документ, он также подвергнется преобразованию. Для того чтобы избежать этого, в преобразование включается шаблонное правило, которое указывает, что элементы xsl:stylesheet
следует игнорировать:
К сожалению, приходится констатировать тот факт, что описанную возможность (хотя она и включена в спецификацию языка XSLT) поддерживают очень немногие процессоры и поэтому пока что на нее не следует полагаться.
Включение документа в преобразование
Другой возможностью объединения документов и преобразований является включение элемента документа в преобразование в виде элемента верхнего уровня.
Поскольку преобразование также является XML-документом, доступ к данным, которые оно содержит можно получить при помощи функции document
, так же, как если бы документ преобразования был внешним документом. Функция document
, которой в качестве параметра была передана пустая строка, возвращает множество, состоящее из корневого узла самого преобразования. То есть, если документ был включен в преобразование в качестве элемента верхнего уровня с именем, к примеру, user:input
, получить доступ к нему можно при помощи выражения
document('')/xsl:stylesheet/user:input
Пример
Листинг 4.22. Входящий документ
Листинг 4.23. Преобразование
version="1.0"
xmlns:user="urn:user"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="user">
select="document('')/xsl:stylesheet/user:input"/>
Листинг 4.24. Выходящий документ
Следует обратить внимание на следующие особенности этого примера.
□ Элементы верхнего уровня в обязательном порядке должны иметь ненулевое пространство имен. Поэтому мы включили элемент input
и все его дочерние узлы в пространство имен urn:user
. В листинге 4.23 эти элементы выделены полужирным шрифтом.
□ В шаблонах, которые обрабатывают элементы включенного документа, должны указываться паттерны, соответствующие расширенным именам этих элементов, то есть не input
, a user:input
.
□ Чтобы не выводить объявления пространств имен в выходящем документе, мы включили префикс user
в атрибут exclude-result-prefixes
элемента xsl:stylesheet
.
Как можно видеть, включение элемента input
как элемента верхнего уровня породило определенные проблемы. Для того чтобы избежать их, можно воспользоваться маленьким фокусом — включать документ не как элемент верхнего уровня, а в элемент верхнего уровня.
Пример
Результат следующего преобразования в точности совпадает с результатом преобразования в предыдущем примере.
Листинг 4.25. Пользовательские данные в элементе верхнего уровня
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
select="document('')/
xsl:stylesheet/xsl:template[@name='input']/input"/>
Хитрость заключается в том, что мы обрабатываем содержимое именованного шаблона, которое вполне может принадлежать нулевому пространству имен. Единственное, что следует иметь в виду — это то, что этот шаблон не должен конфликтовать с другими шаблонами.
В отличие от предыдущего варианта с преобразованием, включенным в документ, этот способ является гораздо более работоспособным. Минусом его является только то, что на вход все равно должен подаваться какой-нибудь XML-документ, даже если его содержимое и не обрабатывается.
Литеральные элементы результата
Как мы уже видели из множества примеров, преобразования состоят не только из элементов языка XSLT. Например, в шаблоне
<���В/>
элемент B
не принадлежит пространству имен XSLT и, следовательно, не считается XSLT-элементом. Такие элементы называются литеральными элементами результата (англ. literal result elements).
Когда процессор выполняет шаблон, содержащий литеральные результирующие элементы, для них в результирующем документе создаются элементы с тем же расширенным именем и атрибутами, содержимым которых является результат выполнения содержимого литерального элемента в преобразовании.
Читать дальше