Эта глава посвящена принятию решений, сортировке и различным способам обработки данных в ХМL-документах. Мы рассмотрим элементы
Однако эти элементы не предоставляют такой точности, как в языках программирования. Поэтому я также представлю в этой главе расширения XSLT, в том числе элемент рабочего проекта XSLT 1.1
Кроме того, в этой главе мы также рассмотрим, как перенумеровать элементы в документе, что делать в случае, когда ваш процессор XSLT не поддерживает определенное расширение, и многое другое. Я начну с наиболее часто используемого элемента из рассматриваемых в данной главе:
Элемент <xsl:if>
При помощи элемента
• test (обязательный). Устанавливается в значение логического (Boolean, true/false) условия, которое вы хотите проверить.
Элемент заключает в себе тело шаблона.
Вот как это работает: вы включаете тело шаблона внутрь элемента
Можно проверять любое выражение XPath. Для преобразования его в значения true/false в элементе
• если выражение вычисляется в набор узлов, оно трактуется как true, когда набор узлов содержит хотя бы один узел;
• выражение-строка считается true, если строка не пуста;
• фрагмент результирующего дерева трактуется как true, если содержит узлы;
• если результат выражения — число, он считается true, когда отличен от нуля.
Элемент
В листинге 5.1 я перечисляю планеты в planets.xml одну за другой и добавляю горизонтальное правило HTML, элемент
(horizontal rule), после последнего элемента — но только после последнего. При помощи
Листинг 5.1. Применение <xsl:if>
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Planets
is planet number
Вот результат — как видите, элемент
появляется только после последней перечисленной планеты:
Planets
Mercury is planet number 1 from the sun.
Venus is planet number 2 from the sun.
Earth is planet number 3 from the sun.
Рассмотрим еще один пример — преобразование XML-XML, в котором перечисляются планеты из planets.xml. Однако я хочу, чтобы выводилось не просто «The first three planets are: Mercury Venus Earth» (первые три планеты: Меркурий Венера Земля), a «The first three planets are: Mercury, Venus, and Earth». Необходимые знаки пунктуации можно добавить, определяя текущий элемент при помощи функции position и проверяя позицию при помощи
Листинг 5.2. Второй пример применения <xsl:if>
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
The Planets
The first three planets are:
Вот результат:
The Planets
The first three planets are: Mercury, Venus, and Earth
Как видите, я смог добавить правильные знаки пунктуации, определяя место в документе при помощи
При помощи
Листинг 5.3. Обнаружение ошибок при помощи <xsl:if>
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
The Planets
The first three planets are:
Each planet must have a name!
Чтобы проверить работу этого кода, я задал один из элементов
.
.
.
Вот как происходит обработка примера в Xalan:
C:\planets>java org.apache.xalan.xslt.Process -IN planets.xml -XSL errors.xsl -OUT new.xml
file:///C:/XSL/w.xsl: Line 18: Column 38: Each planet must have a name!
XSLT Error (javax.xml.transform.TransformerException): Stylesheet directed termination
Если вы знакомы с конструкцией if в языках программирования, вы знаете, что инструкция if обычно сопровождается инструкцией else, которая выполняется при ложности условия в if. Но в XSLT нет элемента
Элементы <xsl:choose>, <xsl:when> и <xsl:otherwise>
Элемент
У элемента
Вот как это работает: в элемент
В предыдущем разделе для осуществления этого преобразования нам потребовалось три элемента
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
The Planets
The first three planets are:
Each planet must have a name!
Теперь то же самое можно сделать при помощи единственного элемента
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
The Planets
The first three planets are:
Each planet must have a name!
.
.
.
Нам нужно проверить, в каком месте документа мы находимся, при помощи включения нескольких элементов
• test (обязательный). Принимает логическое (Boolean) значение (true/false) проверяемого условия.
Элемент
Атрибут проверки принимает значение true/false выражения, определяющего, будет ли применяться заключенное в элементе
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
The Planets
The first three planets are:
Each planet must have a name!
.
.
.
Эти два элемента
У элемента
Листинг 5.4. Применение <xsl:choose>
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
The Planets
The first three planets are:
Each planet must have a name!
Вот как это работает; этот код дает тот же результат, что и код, проверяющий позицию элементов
The Planets
The first three planets are: Mercury, Venus, and Earth.
Вот еще один пример преобразования XML-XML. В этом случае я преобразую planets.xml в новый XML-документ, сохраняя только название каждой планеты и добавляя описание:
The Planets
Это преобразование можно реализовать, выбирая значение каждого элемента
Листинг 5.5. Второй пример <xsl:choose>
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
The Planets
Each planet must have a name!
Вот и все.
Предположим теперь, что нам нужно добавить в каждый элемент
Отобразить названия различных планет при помощи элемента
Листинг 5.6. Форматирование при помощи <xsl:choose>
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Planets
<В>
Вот результирующий документ:
Planets
Mercury
Venus
Earth
Как вы видели, при помощи
Элемент <xsl:for-each>
Элемент
<XSL:FOR-EACH> ПРОТИВ <XSL:APPLY-TEMPLATES>
Вы могли заметить, что это описание практически такое же, как и у элемента <xsl:apply-templates>, и я сравню элементы <xsl:for-each> и <xsl:apply-templates> через несколько страниц.
У элемента
• select (обязательный). Принимает значение выражения XPath, возвращающее набор узлов, который нужно обработать в цикле.
Элемент может содержать ноль или более элементов
В теле шаблона функция position возвращает позицию текущего узла в наборе узлов, a last возвращает число узлов в наборе. Если
Предположим, нам нужно отформатировать все названия планет, заключив их в элементы HTML <Р>, — это можно сделать следующим образом:
<Р>
Но что делать, если у некоторых планет по два названия, как, например:
Это проблема, поскольку атрибут select элемента
Листинг 5.7. Применение <xsl:for-each>
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Эта таблица стилей охватывает все элементы
Mercury
Closest planet to the sun
Venus
Earth
Вот еще один пример, впервые появившийся в главе 3, «Создание и применение шаблонов», где при помощи элемента
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Следующий пример появился в главе 2, «Создание и применение таблиц стилей». Это упрощенная таблица стилей, в которой нельзя использовать какие-либо элементы высокого уровня, то есть нельзя использовать
The Planets Table
The Planets Table
| Name | Mass | Radius | Day |
Эта упрощенная таблица стилей форматирует planets.xml в planets.html практически так же хорошо, как и шаблон, использующий
Как правило,
Элемент
Листинг 5.8. Второй пример <xsl:for-each>
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
И вот результат:
Mercury
.0553
58.65
1516
.983
43.4
Venus
.815
116.75
3716
.943
66.8
Earth
1
1
2107
1
128.4
Сортирующие элементы
При помощи элемента
• select (необязательный). Принимает значение выражения XPath, возвращающего набор узлов для сортировки. По умолчанию — «string(.)»;
• order (необязательный). Задает порядок сортировки, устанавливается в «ascending» (по возрастанию) или «descending» (по убыванию);
• case-order (необязательный). Определяет, будут ли буквы в верхнем регистре располагаться перед буквами в нижнем регистре. Устанавливается в «upper-first» (сначала верхний) или «lower-first» (сначала нижний);
• lang (необязательный). Задает язык, чьи соглашения о сортировке будут применяться. Устанавливается в код языка, допустимый в атрибуте xml:lang;
• data-type (необязательный). Определяет, будет ли сортировка вестись в алфавитном или числовом порядке. Устанавливается в «text» (текст), «number» (число) или в QName.
Этот элемент не включает содержимое. Его следует применять внутри элементов
В листинге 5.9 я только отсортирую элементы
Листинг 5.9. Сортировка данных
The Sorted Planets Table
The Sorted Planets Table
| Name | Mass | Radius | Day |
А вот результат. Обратите внимание на то, что планеты действительно отсортированы как Earth, Mercury и затем Venus:
The Sorted Planets Table
The Sorted Planets Table
| Name | Mass | Radius | Day |
| Earth | 1 | 2107 | 1 |
| Mercury | .0553 | 1516 | 58.65 |
| Venus | .815 | 3716 | 116.75 |
Вид документа показан на рис. 5.1.
Рис. 5.1. Сортировка при помощи упрощенного шаблона
При помощи атрибута select можно указать, что нужно сортировать. Например, таким образом можно отсортировать планеты по плотности (листинг 5.10).
Листинг 5.10. Сортировка планет по плотности
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Planets
Planets sorted by density
| Planet | Mass | Day | Density |
Вот результаты этого преобразования:
Planets
Planets sorted by density
Н1>
| Planet | Mass | Day | Density |
| Venus | .815 | 116.75 | .943 |
| Mercury | .0553 | 58.65 | .983 |
| Earth | 1 | 1 | 1 |
По умолчанию
Убывающий порядок сортировки задается установкой у элемента
НОВОЕ В XSLT 2.0
Одним из важных преимуществ XSLT 2.0 является поддержка схем XML, и W3C планирует внести в XSLT 2.0 возможность сортировки по любому типу данных, определенному в схеме документа, так же, как сейчас можно сортировать по строкам или числам.
Сортировка по нескольким критериям
Стоит отметить, что при сортировке можно применять несколько критериев — для этого просто примените несколько элементов
На этом мы заканчиваем обсуждение сортировки, и я перехожу к сопутствующей теме: нумерации.
Элемент <xsl:number>
При помощи элемента
Элемент
• level (необязательный). Определяет, как будут присваиваться последовательные числа. Устанавливается в «single» (один), «multiple» (несколько) или «any» (любой). Значение по умолчанию — «single»;
• count (необязательный). Определяет, какие узлы нужно подсчитывать. Устанавливается в образец;
• from (необязательный). Определяет точку начала отсчета. Устанавливается в образец;
• value (необязательный). Форматируемое число;
• format (необязательный). Определяет формат вывода. Устанавливается в шаблон значений атрибута, возвращающий строку форматирования;
• lang (необязательный). Определяет язык, чьи соглашения следует использовать для нумерации. Устанавливается в код языка, который можно применять в атрибуте xml:lang;
• letter-value (необязательный). Позволяет выбрать различные схемы нумерации. устанавливается в «alphabetical» (алфавитная) или «traditional» (обычная);
• grouping-separator (необязательный). Символ для разделения групп разрядов — например, запятая. Устанавливается в шаблон значений атрибутов, возвращающий единственный символ;
• grouping-size (необязательный). Количество разрядов в каждой группе — определяет место применения разделителя групп разрядов. Устанавливается в шаблон значений атрибутов, возвращающий число.
СОВЕТ ПО НУМЕРАЦИИ
Как можно видеть из этого списка атрибутов, существует весьма много возможных схем нумерации. Операции нумерации могут стать довольно сложными, поэтому есть один прием: если нумерация будет становиться слишком сложной и запутанной, я просто выведу результирующий документ без нумерации и затем воспользуюсь второй таблицей стилей, которая применит нумерацию.
Существует три основных способа нумерации, в зависимости от установки атрибута уровня (level): «single», «multiple» или «any». В следующих разделах мы по очереди рассмотрим каждую из этих схем, начав с одноуровневой нумерации, которая установлена по умолчанию.
Одноуровневая нумерация
Одноуровневая нумерация — это простая нумерация, когда перенумеровываются узлы-братья на одном уровне. Этот тип нумерации установлен по умолчанию. В листинге 5.11 при помощи одноуровневой нумерации перенумеровываются планеты в planets.xml.
Листинг 5.11. Одноуровневая нумерация
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
The Planets Table
The Planets Table
| Name | Mass | Radius | Day |
.
.
.
А вот результат:
The Planets Table
The Planets Table
| Name | Mass | Radius | Day |
| 1. Mercury | .0553 (Earth = 1) | 1516 miles | 58.65 days |
| 2. Venus | .815 (Earth = 1) | 3716 miles | 116.75 days |
| 3. Earth | 1 (Earth = 1) | 2107 miles | 1 days |
Этот результат показан на рис. 5.2.
Рис. 5.2. Одноуровневая нумерация элементов
По умолчанию при нумерации используются числа, но есть и другие возможности. Например, если бы я использовал
The Planets Table
The Planets Table
| Name | Mass | Radius | Day |
| a. Mercury | .0553 (Earth = 1) | 1516 miles | 58.65 days |
| b. Venus | .815 (Earth = 1) | 3716 miles | 116.75 days |
| Name | Mass | Radius | Day |
.
.
.
Получаем результат (заметьте, что текст каждого элемента
The Planets Table
The Planets Table
1. Planets Table
| Name | Mass | Radius | Day |
| 2. Mercury | .0553 (Earth = 1) | 1516 miles | 58.65 days |
| 3. Venus | .815 (Earth = 1) | 3716 miles | 116.75 days |
| 4. Earth | 1 (Earth = 1) | 2107 miles | 1 days |
При помощи атрибута from можно указать, с какого узла-предка начинать отсчет; например, если установить узел-предок в элемент
то процессор XSLT осуществит обратный просмотр только до первого предка
Многоуровневая нумерация
Элемент
В примере я нумерую каждый уровень в иерархии элементов planets.xml, установив атрибут count в «*» для выбора всех элементов. Можно также указать формат нумерации при помощи атрибута format. При многоуровневой нумерации атрибут format задает формат для различных уровней, например «1.1.1.» задает нумерацию 1., 2., … и т.д. для узлов верхнего уровня, 1.1., 1.2., … и т.д. для узлов уровнем ниже и 1.2.1., 1.2.2., … и т. д. для следующего уровня вниз. Вот как выглядит таблица стилей для этого примера в листинге 5.13.
Листинг 5.13. Многоуровневая нумерация
<хsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Вот результат преобразования planets.xml в новый XML-документ, в котором перенумерованы все уровни элементов в соответствии с иерархией документа:
На этом мы завершаем рассмотрение нумерации документов и переходим к последней теме этой главы — расширяемости XSLT.
Расширяемость XSLT
Несмотря на кажущуюся сложность XSLT, он во многих отношениях ограничен по сравнению с языками программирования, и в процессорах XSLT сразу же начали появляться расширения XSLT. Например, Saxon представил элемент
Можно представить, с каким беспокойством на это смотрит W3C. Его работа, в принципе, заключается в стандартизации работы таких языков, как XSLT, но производители постоянно представляли свои собственные, нестандартные расширения в виде новых элементов и функций. С другой стороны, W3C не может предугадать все новые элементы и функции, поэтому консорциум начал работать над стандартизацией способов включения функций расширения и элементов в XSLT. Расширения должны удовлетворять ряду общих правил:
• расширения должны использовать пространства имен во избежание конфликтов с элементами XSL;
• процессор XSLT должен быть в состоянии распознать применение расширения — и в случае ошибки расширения реагировать хорошо определенным способом;
• таблица стилей должна быть в состоянии проверить, доступно ли определенное расширение, и если нет, вернуться назад.
НОВОЕ В XSLT 2.0
Легко представить сложности W3C даже с этими общими правилами, и комитет XSLT 2.0 собирается исследовать возможность реализации всех расширений на «чистом» XSLT, вообще не прибегая к каким-либо внешним языкам программирования.
W3C разрешил расширения двух видов, главным образом, потому, что они уже были приняты де-факто — функции расширения и элементы расширения. Хотя они пользуются популярностью, это весьма неясная область, поскольку различные производители представили разные способы их реализации.
В XSLT 1.0 проверить доступность функции расширения можно при помощи функции function-available, а доступность элемента расширения — при помощи функции element-available.
XSLT 2.0 готовится определить стандартные средства связывания XSLT с элементами расширения и, вероятно, они будут гораздо лучше проработаны, чем имеющиеся сейчас.
Давайте посмотрим на все это в работе. В следующих разделах мы рассмотрим и функции, и элементы расширения, начав с функций.
ИНИЦИАТИВА EXSLT
Теперь, после того, как механизмы расширения в рабочем проекте XSLT 1.1 были отложены до XSLT 2.0, роль других разнообразных попыток стандартизации расширений XSLT значительно повысилась. Познакомьтесь, например, с EXSLT на www.exslt.org. EXSLT — это инициатива открытого сообщества, работающего над стандартизацией расширений XSLT.
Функции расширения
В XSLT 1.0 W3C определил способ отделения функций расширения от встроенных функций, установив требование, чтобы для обращения к функциям расширения использовались имена с заданным пространством имен, как в starpowder:calculate(). В XSLT 1.0 также имеется функция function-available() для проверки наличия функции по ее имени.
В рабочем проекту XSLT 1.1 на функции расширения были наложены некоторые дополнительные ограничения:
• функции расширения должны работать как встроенные функции;
• для Java и ECMAScript должны быть реализованы привязки к языку;
• механизм должен позволять естественное расширение для поддержки других языков в будущем;
• для реализации переносимой привязки функции расширения для любого конкретного языка не должен быть нужен процессор;
• процессор, реализующий функции расширения для любого языка, чья привязка обеспечивается спецификацией XSLT, должен соответствовать этим языкам;
• должны быть разрешены как встроенные реализации функций расширения, так и внешние;
• в функции расширения должно быть возможно передавать аргументы всех типов данных XPath;
• функции расширения должны иметь возможность возвращать в качестве результата все типы данных XPath;
• функции расширения должны иметь возможность создавать и возвращать наборы узлов фрагментов XML;
• должна иметься возможность включать или импортировать функции расширения из другой таблицы стилей;
• при неоднозначности выбора реализации функции расширения процессор должен выдать ошибку и прекратить работу;
• процессор должен преобразовывать аргументы способом, согласованным со встроенными функциями;
• функции расширения должны быть способны вернуть объект любого типа основного языка;
• должна существовать возможность передать в функцию расширения объект любого типа основного языка.
Вплоть до недавнего времени процессоры XSLT полностью самостоятельно определяли способ реализации функций расширения. Например, в Saxon и Xalan существует возможность непосредственно выполнять код Java, если определить пространство имен, задающее класс Java в качестве последней части URI. Я поступил так в следующем случае, определив пространство имен Date, соответствующее классу Java Date:
xmlns:xsl=http://www.w3.org/1999/XSL/Transform
xmlns:Date="http://www.saxon.com/java/java.util.Date">
.
.
.
После этого я могу воспользоваться такими функциями класса Date Java, как toString и new, для того чтобы заключить текущую дату в элементы заголовка <Н1> HTML в выходном документе (листинг 5.14). Листинг 5.14. Применение функций Date Java
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:Date="http://www.saxon.com/java/java.util.Date">
The Planets Table
The Planets Table
| Name | Mass | Radius | Day |
Результат применения этой функции приведён на рис. 5.3.
Рис. 5.3. Применение функции расширения
Вот работоспособная схема и заодно веский повод включить Java в XSLT. Тем не менее, в XSLT 1.1 был представлен элемент
Элемент <xsl:script>
Элемент
• implements-prefix (необязательный). Задает имя пространства имен функции расширения, которую реализует этот элемент. Принимает значение NCNAME;
• language (необязательный). Задает язык, используемый функцией расширения. Устанавливается в «ecmascript» (стандарт JavaScript), «javascript», «java» или QNAME, не являющееся NCNAME;
• src (необязательный). Предоставляет URI, в котором реализована функция расширения. Например, это может быть класс Java;
• archive (необязательный). Задает архивы, которые необходимо загрузить перед запуском функции расширения, если они есть. Принимает значения списка URI, разделенного символами-разделителями.
Элемент содержит символьные данные (Microsoft использует раздел CDATA), реализующие функцию или функции расширения.
Как теперь связать функцию, определенную в элементе
function makeMoney(e) {
.
.
.
}
function makeMoreMoney(e) {
.
.
.
}
В зависимости от вашего процессора XSLT, может оказаться хорошим решением заключить такого рода сценарии в раздел CDATA:
function makeMoney(e) {
.
.
.
}
function makeMoreMoney(e) {
.
.
.
}
]]>
Теперь при помощи пространства имен «starpowder» можно указать, что вызывается функция расширения:
Вот и все (если ваш процессор XSLT это поддерживает). Если вместо сценария вы хотите указать класс Java, воспользуйтесь атрибутом src:
РАБОТА С ВНЕШНИМИ РЕСУРСАМИ
Атрибут src также используется, если есть архив подпрограмм JavaScript, как, например, src="archives.js".
Из всех известных мне процессоров XSLT элемент
Следующий пример демонстрирует работу
Как обсуждалось в главе 2 в разделе «Преобразование документов XML при помощи Internet. Explorer», для просмотра XML-документа, использующего таблицу стилей XSL, в Internet Explorer, версии 5.5 и младше в документ необходимо внести некоторые изменения (если только вы не установили последний разборщик MSXML или не используете недавно появившуюся версию браузера 6.0, хотя и в этом случае нужно применять «text/xsl»). Для начала в таблице стилей XSL используйте тип MIME «text/xsl», а не «text/xml». Я также задал URI для таблицы стилей «kilometers.хsl» следующим образом (листинг 5.15).
Листинг 5.15. Установка использования kilometers.xsl для planets.xml в Internet Explorer
.
.
.
Для преобразования таблицы стилей kilometers.xsl для работы в IE 5.5 или младше я воспользовался пространством имен XSL, которое использует IE, и добавил элемент
.
.
.
.
.
.
В соответствии с требованиями Internet Explorer, код должен быть заключен в раздел CDATA. Здесь я определил функцию milesToKilometers, которая принимает узел, читает текст узла в свойстве text и преобразует текст в число миль при помощи функции JavaScript parseInt. Далее я умножаю число миль на 1,6, чтобы получить километры, и возвращаю результат:
function milesToKilometers(e) {
miles = parseInt(e.text);
return miles * 1.6;
}
]]>
.
.
.
Поскольку пока в Internet Explorer нельзя связать пространство имен с функцией расширения, для их вызова используется специальный элемент Microsoft
Листинг 5.16. kilometers.xsl
function milesToKilometers(e) {
miles = parseInt(e.text);
return miles * 1.6;
}
]]>
The Planets Table
The Planets Table
| Name | Mass | Radius | Day |
Вот и все, результат этого преобразования приведен на рис. 5.4.
Рис. 5.4. Применение функции расширения в Internet Explorer
Со временем производители будут поставлять все больше и больше функций расширения. Как можно определить, доступна ли заданная функция расширения? Для этого служит функция function-available.
Применение функции function-available
Функция XSLT 1.0 function-available служит для проверки доступности функции. В следующем примере я хочу воспользоваться функцией расширения starpowder:calculate для математических вычислений, а если она недоступна, я отправляю в результирующий документ текст «Sorry, can't do math today.» (Извините, сегодня математические вычисления не работают.), хотя можно, конечно, прекратить обработку и вывести сообщение об ошибке при помощи элемента
Внешние объекты
В рабочем проекте XSLT 1.1 для поддержки функций расширения появился новый тип данных — внешний объект (external object). Переменной XSLT, о которой пойдет речь в главе 9, может быть присвоен внешний объект — так же, как и один из четырех типов данных XPath, поддерживаемых в XSLT (строка, число, логическое значение, набор узлов). Внешний объект представляет объект, который создается внешним языком программирования, возвращается функцией расширения и не может быть преобразован в один из четырех типов данных XPath. Тип данных «external object» был добавлен в XSLT для того, чтобы предоставить вам безопасную «оболочку» для таких данных. Пока еще никто не реализовал поддержку внешних объектов, но это ожидается в скором времени.
Элементы расширения
Элементы расширения — это элементы, добавленные в XSLT пользователем или производителем. В рабочем проекте XSLT 1.1 для элементов расширения был установлен ряд правил, и в XSLT 2.0 предполагается более широкая их поддержка.
В рабочем проекте XSLT 1.1 правила определяли, что элементами расширения должны быть определенные пользователем или производителем элементы, не являющиеся элементами верхнего уровня. Они должны принадлежать к пространству имен, которое было определено как пространство имен расширений.
Для определения пространства имен расширений применяется атрибут extension-element-prefixes в элементе
Ниже приведен пример. Xalan позволяет вам создать несколько выходных документов при помощи своего элемента расширения
.
.
.
Теперь в таблице стилей XSLT, которую я назвал redirect.xsl, я определяю пространство имен «redirect» так, чтобы оно соответствовало классу Java, который поддерживает ее в Xalan: org.apache.xalan.lib.Redirect. Я также устанавливаю атрибут extension-element-prefixes элемента
version="1.0"
xmlns:lxslt=http://xml.apache.org/xslt"
xmlns:redirect="org.apache.xalan.lib.Redirect"
extension-element-prefixes="redirect">
.
.
.
В этот момент мне ничто не мешает применить элемент расширения
version="1.0"
xmlns:lxslt="http://xml.apache.org/xslt"
xmlns:redirect="org.apache.xalan.lib.Redirect"
extension-element-prefixes="redirect">
Операция завершена; вот как это может выглядеть при использовании Xalan в Windows:
C:planets>java org.apache.xalan.xslt.Process -IN planets.xml -XSL redirect.xsl -OUT new.xml
При этом будет создан файл redirected.xml, который выглядит следующим образом:
.
.
.
Применение функции element-available
Для проверки доступности элемента служит функция XSLT 1.0 element-available. В следующем примере я проверяю наличие элемента с названием
Есть еще один способ обработать случай отсутствия элемента расширения — элемент
Элемент <xsl:fallback>
При помощи элемента XSLT 1.0
У элемента
В следующем примере я создам элемент
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:lxslt="http://xml.apache.org/xslt"
xmlns:redirect="org.apache.xalan.lib.Redirect"
extension-element-prefixes="redirect">
На этом мы заканчиваем введение в работу с данными в документах XML. В следующей главе мы разберем эту тему и узнаем, как изменять содержимое документа и создавать новые элементы, атрибуты и инструкции обработки.