- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Технология XSLT - Алексей Валиков
Шрифт:
Интервал:
Закладка:
function-available('rot:X')
В данном случае true будет означать, что функция rot:X может быть вызвана, false — что функция в силу каких-то причин недоступна.
Функция function-available может помочь в создании преобразований, которые используют расширения, но при этом в некоторой степени сохраняют переносимость между различными процессорами. Достаточно написать несколько вариантов вызова функции расширения для каждого из процессоров, на которых преобразование должно работать, а затем использовать вариант с доступной данному процессору функцией расширения.
ПримерДля того чтобы обеспечить работоспособность расширения, реализованного классом de.fzi.xslt.rot в наиболее распространенных XSLT-процессорах, написанных на Java (как-то: Saxon, Xalan и Oracle XSLT Processor), прежде всего необходимо объявить соответствующие пространства имен:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2000/svg"
xmlns:saxon="java:de.fzi.xslt.rot"
xmlns:xalan="xalan://de.fzi.xslt.rot"
xmlns:oracle="http://www.oracle.com/XSL/Transform/java/de.fzi.xslt.rot"
exclude-result-prefixes="saxon xalan oracle">
...
Префикс saxon соответствует интерфейсу расширений в XSLT-процессоре Saxon, префикс xalan — процессору Xalan и префикс oracle — Oracle XSLT Processor.
Теперь осталось только найти поддерживаемый вариант расширения и произвести соответствующий вызов.
Листинг 10.9<xsl:choose>
<xsl:when test="function-available('saxon:X') ">
<line
x1="{saxon:X($x1, $y1, $alpha) + 100}"
y1="{saxon:Y($x1, $y1, $alpha) + 100}"
x2="{saxon:X($x2, $y2, $alpha) + 100}"
y2="{saxon:Y($x2, $y2, $alpha) + 100}"/>
</xsl:when>
<xsl:when test="function-available('xalan:X')">
<line
x1="{xalan:X($x1, $y1, $alpha) + 100}"
y1="{xalan:Y($x1, $y1, $alpha) + 100}"
x2="{xalan:X($x2, $y2, $alpha) + 100}"
y2="{xalan:Y($x2, $y2, $alpha) + 100}"/>
</xsl:when>
<xsl:when test="function-available('oracle:X')">
<line
x1="{oracle:X($x1, $y1, $alpha) + 100}"
y1="{oracle:Y($x1, $y1, $alpha) + 100}"
x2="{oracle:X($x2, $y2, $alpha) + 100}"
y2="{oracle:Y($x2, $y2, $alpha) + 100}"/>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
<xsl:text>Necessary extension function is not available.</xsl:text>
<xsl:text>
Supported processors are:</xsl:text>
<xsl:text>
Saxon, Xalan, Oracle XSLT Processor.</xsl:text>
</xsl:message>
</xsl:otherwise>
</xsl:choose>
В случае, если хотя бы одна из функций saxon:X, xalan:X, oracle:X будет доступна при обработке, она будет использована процессором для создания атрибутов элемента line. В противном случае, процессор прервет выполнение преобразования и выведет указанное в элементе xsl:message сообщение.
Нельзя не согласиться с тем, что приведенный выше способ не отличается элегантностью. Реализовывать свой вариант для каждого существующего процессора может быть довольно трудоемкой задачей — но такова уж плата за возможности расширений.
Функция расширения nodeset
Одной из самых полезных функций расширения, которая, как правило, уже штатно реализована во многих процессорах (то есть, не требует дополнительного программирования) является функция nodeset. Эта функция позволяет в обход прямого запрета спецификации конвертировать результирующий фрагмент дерева во множество узлов.
Предположим, что мы создаем в переменной rtf результирующий фрагмент дерева следующего вида:
<xsl:variable name="rtf">
<item>1</item>
<item>2</item>
<item>3</item>
</xsl:variable>
При попытке вычислить выражение вида $rtf/item[2] процессор в соответствии со спецификацией должен вывести ошибку, поскольку в этом фильтрующем выражении (см. продукцию [XP20] FilterExpr) переменная rtf должна содержать множество узлов, а не фрагмент дерева.
Текущая спецификация языка XPath совершенно явно говорит о том, что ни один тип данных не может быть преобразован во множество узлов. Функция nodeset действует в обход этого запрещения: она принимает на вход результирующий фрагмент дерева и возвращает множество, состоящее из корневого узла этого фрагмента.
В разных процессорах эта функция имеет различный синтаксис: она может носить имя nodeset или node-set, или nodeSet, однако семантика ее во всех случаях одинакова:
nodeset nodeset(result-tree-fragment)
Функция принимает на вход единственный аргумент, являющийся фрагментом дерева и возвращает множество узлов, состоящее из его корня.
ПримерПредположим, что мы обрабатываем входящий документ, содержащий трехбуквенные коды языков.
Листинг 10.10. Входящий документ<items>
<item>ENG</item>
<item>FRE</item>
<item>GER</item>
<item>GRE</item>
<item>ITA</item>
<item>NOR</item>
<item>POR</item>
<item>SPA</item>
</items>
Фрагмент шаблона, обрабатывающий этот список, может выглядеть следующим образом:
<select name="language">
<xsl:for-each select="items/item">
<option>
<xsl:value-of select="."/>
</option>
</xsl:for-each>
</select>
Если в преобразовании нам понадобится доопределить входящий список кодами RUS и UKR, не исправляя входящий документ, можно поступить следующим образом:
□ создать в переменной фрагмент дерева, содержащий элементы item входящего документа плюс элементы item, доопределяющие этот список;
□ преобразовать дерево в список узлов;
□ обрабатывать список узлов точно так же, как мы бы обрабатывали сам входящий документ.
Преобразование, реализующее эти три шага, приведено ниже.
Листинг 10.11. Преобразование<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
exclude-result-prefixes="xalan">
<xsl:template match="items">
<!--
| Создаем переменную tree, содержащую элементы item
| входящего документа а также два дополнительных элемента
+-->
<xsl:variable name="tree">
<xsl:copy-of select="item"/>
<item>RUS</item>
<item>UKR</item>
</xsl:variable>
<!--
| Конвертируем переменную tree во множество узлов,
| результат присваиваем переменной items
+-->
<xsl:variable name="items" select="xalan:nodeset($tree)"/>
<!--
| Обрабатываем узлы $items/item точно так же,
| как мы обрабатывали бы узлы items/item
+-->
<select name="language">
<xsl:for-each select="$items/item">
<option>
<xsl:value-of select="."/>
</option>
</xsl:for-each>
</select>
</xsl:template>
</xsl:stylesheet>
Результат этого преобразования приведен на следующем листинге.
Листинг 10.12. Выходящий документ<select name="language">
<option>ENG</option>
<option>FRE</option>
<option>GER</option>
<option>GRE</option>
<option>ITA</option>
<option>NOR</option>
<option>POR</option>
<option>SPA</option>
<option>USA</option>
<option>RUS</option>
<option>UKR</option>
</select>
Вне всякого сомнения, функция nodeset является одним из наиболее востребованных в XSLT расширений, ведь возможность не только создавать, но и манипулировать уже созданными древовидными структурами является чрезвычайно полезной.
В качестве одного из примеров применения функции nodeset можно привести реализацию с ее помощью многошаговых преобразований.
В качестве примера рассмотрим схему трансформации, изображенную на рис. 10.3, в которой документ А сначала нужно обработать преобразованием 1, затем полученный результат (документ В) обработать преобразованием 2. Конечным результатом цепочки преобразований в данном случае является документ С.
Рис. 10.3. Двухшаговое преобразование
При выполнении преобразования процессор применяет шаблоны ко множеству узлов входящего документа и выстраивает результирующее дерево. Таким образом, для того, чтобы повторно применить шаблоны к уже обработанному документу (читай: к полученному дереву), нужно просто иметь возможность преобразовывать дерево во множество узлов.