- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Технология XSLT - Алексей Валиков
Шрифт:
Интервал:
Закладка:
В преобразованиях часто бывает необходимо использовать массивы статических данных, и логично было бы присваивать их переменным, чтобы использовать затем в выражениях. К несчастью, простое создание фрагмента дерева в переменной мало помогает. Конструкция
<xsl:variable name="colors">
<color>#0E0E0E</color>
<color>#FFFFFF</color>
</xsl:variable>
создает в переменной colors результирующий фрагмент дерева. В соответствии со спецификацией XPath 1.0 выражение $colors/color[1] будет некорректным, поскольку типом colors является результирующий фрагмент дерева, который не может быть напрямую преобразован во множество узлов. Иными словами, совершенно логичное и оправданное выражение не является корректным. Конечно, существуют способы обойти этот запрет — с помощью расширений и тому подобного, но нельзя не согласиться с тем, что результирующие фрагменты являются самой большой занозой в XSLT 1.0.
XSLT 1.1 исправляет этот просчет. Переменная colors, определенная выше, будет иметь своим значение не фрагмент дерева, а множество из одного, корневого, узла этого фрагмента и ее можно использовать везде, где только можно использовать тип данных node-set.
Несколько выходящих документов
Как известно, преобразование в XSLT 1.0 имеет один основной входящий документ (плюс документы, доступные при помощи функции document) и ровно один выходящий документ. То есть, для того, чтобы сгенерировать на основе одного входящего документа несколько выходящих следует просто выполнить несколько преобразований.
Следуя многочисленным запросам программистов, почти все разработчики XSLT-процессоров предоставили в своих продуктах возможность генерировать несколько выходящих документов непосредственно из одного преобразования. Элемент xsl:document, добавленный в XSLT 1.1, сделал эту возможность стандартной.
ПримерСамым простым применением xsl:document является разбиение одного документа на несколько. Например, имея документ вида
<book>
<chapter>Text 1</chapter>
<chapter>Text 2</chapter>
<chapter>Text 3</chapter>
</book>
мы можем выделить элементы chapter в отдельные файлы, а в самом выходящем документе создать оглавление со ссылками.
Листинг 12.1. Преобразование, использующее элемент xsl:document<xsl:stylesheet
version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="book">
<xsl:copy>
<xsl:apply-templates select="chapter"/>
</xsl:copy>
</xsl:template>
<xsl:template match="chapter">
<chapter href="chapter{position()}.xml"/>
<xsl:document href="chapter{position()}.xml">
<xsl:copy-of select="."/>
</xsl:document>
</xsl:template>
</xsl:stylesheet>
Результатом этого преобразования будут следующие четыре документа.
Листинг 12.2. Главный выходящий документ преобразования<book>
<chapter href="chapter1.xml"/>
<chapter href="chapter2.xml"/>
<chapter href="chapter3.xml"/>
</book>
Листинг 12.3. Документ chapter1.xml<chapter>Text 1</chapter>
Листинг 12.4. Документ chapter2.xml<chapter>Text 2</chapter>
Листинг 12.5. Документ chapter3.xml<chapter>Text 3</chapter>
Дополнительные возможности по расширению
В XSLT 1.1 был введен элемент xsl:script, предоставляющий дополнительные возможности для создания и использования функций расширения. При помощи xsl:script функции расширения могут быть явным образом определены в самом преобразовании.
ПримерВ процессоре, который поддерживает скриптовые языки типа JavaScript, исходный код функций расширения может включаться в само преобразование, например.
Листинг 12.6. Преобразование, включающее функцию расширения<xsl:stylesheet
version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:js="javascript:code">
<xsl:script language="javascript" implements-prefix="js">
function iff(arg1, arg2, arg3) {
if (arg1) {
return arg2;
} else {
return arg3;
}
}
</xsl:script>
...
</xsl:stylesheet>
Атрибут implements-prefix (англ. implements prefix — реализует префикс) связывает определяемую функцию с некоторым пространством имен (как мы отмечали ранее, все функции расширения должны принадлежать ненулевым пространствам имен). При вызове функций из этого пространства имен в XPath-выражениях, процессор будет искать их определения в элементах xsl:script, которые реализуют соответствующий префикс.
Атрибут language определяет язык программирования, в котором написано расширение. Очевидно, язык влияет на то, как будет выполняться расширение — например, должен ли процессор интерпретировать содержимое xsl:script или следует загрузить внешний Java-класс. Естественно, не следует ожидать, что любой процессор сможет выполнять расширения, написанные на произвольных языках программирования — как правило, разработчики XSLT-средств в документации к своим продуктам оговаривают, какие языки расширения они поддерживают. Как следствие, преобразование, использующее расширения, написанные на "непонятном" процессору языке, либо не будут выполнены вообще, либо будут выполнены некорректно.
Помимо двух обязательных атрибутов implements-prefix и language, в элемент xsl:script могут быть включены атрибуты src и archive, которые указывают физическое местоположение кода расширения.
"Внешние" типы данных
Четыре основных типа данных языка XPath (булевый, численный, строковый типы и множества узлов) в первой версии XSLT были расширены типом результирующего фрагмента дерева. В некотором смысле, фрагменты деревьев были "внешним" типом по отношению к XPath, но, тем не менее, многие из функций базовой библиотеки с успехом с этим типом работали.
В XSLT 1.1 была впервые представлена поддержка произвольных внешних типов данных. Функции расширения могут возвращать и оперировать любыми типами данных. Например, в XSLT-процессорах, написанных на Java, в случае использования расширений в качестве значений часто используются произвольные классы.
ПримерФорматирование текущей даты и времени, которое было продемонстрировано в главе 10 элементом ext:date, может быть переписано при помощи функций расширения следующим образом.
Листинг 12.7. Использование внешних типов данных в преобразовании<xsl:stylesheet
version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:Date="java:java.util.Date"
xmlns:SimpleDateFormat="java.text.SimpleDateFormat">
<xsl:variable name="df" select="SimpleDateFormat:new('HH:mm')"/>
<xsl:variable name="now" select="Date:new()"/>
<xsl:template match="/">
<xsl:value-of select="SimpleDateFormat:format($df, $now)"/>
</xsl:template>
</xsl:stylesheet>
Пространства имен с префиксами Date и SimpleDateFormat определяют привязку к Java-классам java.util.Date и java.text.SimpleDateFormat соответственно (в этом примере мы используем формат URI пространств имен, принятый в процессоре Saxon).
Объявление
<xsl:variable name="df" select="SimpleDateFormat:new('HH:mm')"/>
присваивает переменной df результат выполнения конструктора класса SimpleDateFormat со строковым параметром "HH:mm", что эквивалентно Java-коду
SimpleDateFormat df = new SimpleDateFormat("НН:mm");
Иными словами, переменной df был присвоен "внешний" тип данных java.text.SimpleDateFormat. Аналогично, переменная now содержит данные типа java.util.Date. Фактически, этим переменным были присвоены экземпляры соответствующих классов.
Выражение SimpleDateFormat:format($df, $now), использованное в этом преобразовании, представляет собой ни что иное, как применение метода format экземпляра класса SimpleDateFormat, присвоенного переменной df к экземпляру класса Date, присвоенного переменной now. В переводе на Java:
df.format(now);
Надо сказать, что оперирование внешними типами — отнюдь не нововведение XSLT 1.1. Во многих процессорах интерфейсы расширения позволяют функциям возвращать произвольные типы данных. Важно, что теперь эта возможность закреплена в официальном документе Консорциума W3, и следует полагать, что и из второй версии языка она никуда не денется.
Стандартные интерфейсы расширений
Важным дополнением в XSLT 1.1 по сравнению с первой версией языка является определение стандартных интерфейсов расширения для языков IDL, JavaScript/ECMAScript и Java на основе интерфейсов DOM2.