- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Технология XSLT - Алексей Валиков
Шрифт:
Интервал:
Закладка:
Три шага этого преобразования продемонстрированы на рис. 5.1.
Рис. 5.1. Процесс преобразования
Здесь слева показан текущий список узлов, посередине — дерево документа с выделенным пунктиром текущим узлом, справа — генерируемое выходящее дерево.
Результатом этого преобразования будет документ:
<p><b>text</b></p>
Рассмотрим чуть более сложное преобразование документа:
<para>
<bold>text1</bold>
<para>
<bold>text2</bold>
</para>
</para>
Порядок действий в этом случае будет приблизительно следующим.
□ Первым обрабатывается корневой узел. Процессор применяет шаблоны к дочерним узлам (вернее к одному дочернему узлу — элементу para).
□ Шаблон, обрабатывающий элемент para, создает в выходящем документе элемент p и применяет шаблоны к своим дочерним узлам — на этот раз их два, bold и para.
□ Шаблон, обрабатывающий элемент bold, создает в выходящем документе элемент b и текстовый узел со значением "text1".
□ Шаблон, обрабатывающий элемент para, создает в выходящем дереве узел p и применяет шаблоны к дочерним узлам.
□ Единственным дочерним узлом элемента para является элемент bold.
□ Шаблон, обрабатывающий этот элемент bold, создает в выходящем документе элемент b и текстовый узел со значением "text2".
Процесс преобразования показан на рис. 5.2.
Рис. 5.2. Процесс преобразования
Результатом этого преобразования будет документ:
<p>
<b>text1</b>
<p>
<b>text2</b>
</p>
</p>
Атрибут select элемента xsl:apply-templates позволяет выбирать, к каким именно узлам будет применяться этот шаблон. Значение select — это XPath-выражение, которое должно возвращать множество узлов. В случае, если атрибут select указан, шаблоны будут поочередно применяться к каждому из узлов выбранного множества.
ПримерЕсли при обработке элементов para мы хотим обрабатывать только дочерние элементы bold и никакие другие, шаблон обработки элементов para будет записан следующим образом:
<xsl:template match="para">
<p><xsl:apply-templates select="bold"/></p>
</xsl:template>
Результатом обработки документа
<para>
<bold>text1</bold>
<para>
<bold>text2</bold>
</para>
</para>
будет теперь
<p>
<b>text1</b>
</p>
Элемент para, который во входящем документе включен в другой элемент para, не будет обработан по той простой причине, что он не вошел во множество, выбранное XPath-выражением "bold". В то же время, если мы запишем
<xsl:template match="para">
<p><xsl:apply-templates select="bold|para"/></p>
</xsl:template>
то результат будет таким же, как и прежде:
<p>
<b>text1</b>
<p>
<b>text2</b>
</p>
</p>
Следует хорошо понимать разницу между атрибутом select элемента xsl:apply-templates и атрибутом match элемента xsl:template. Атрибут match содержит не XPath-выражение, а паттерн XSLT; в отличие от атрибута select в xsl:apply-templates он не выбирает никакого множества узлов, он используется только для того, чтобы проверить, может ли данный узел обрабатываться этим шаблоном или нет.
Атрибут select элемента xsl:apply-templates наоборот, содержит не паттерн, а выражение, единственным требованием к которому является то, что оно должно возвращать множество узлов. Например, некорректным будет определение вида
<xsl:apply-templates select="para+1"/>
поскольку выражение para+1 не может возвратить множество узлов.
Кроме этого требования, никаких других ограничений на выражения в этом атрибуте нет. В нем можно использовать переменные, содержащие множества узлов, функции, возвращающие множества узлов (например, такие, как id или key), выражения с операциями над множествами (именно таким выражением — выражением объединения было выражение bold|para), пути выборки, фильтрующие выражения, в общем, любые выражения, которые только могут возвращать множества. Например, для того, чтобы обработать содержимое произвольного внешнего XML-документа, в атрибуте select элемента xsl:apply-template следует использовать функцию document.
ПримерОбъявление вида
<xsl:apply-templates select="document('a.xml')//para"/>
применит шаблоны ко всем элементам para документа a.xml.
Режимы
Очень часто в преобразованиях требуется обрабатывать одни и те же узлы, но разными способами. Типичным примером такого рода задачи является генерация оглавления документа вместе с преобразованием его содержимого. Очевидно, что просто шаблонами здесь не обойтись, и чтобы не получить другой результат, нужно каким-то образом указывать, что по-другому должна вестись и обработка.
Эта проблема решается в XSLT просто и элегантно. Атрибут mode элемента xsl:template задает режим этого шаблона. Точно такой же атрибут есть у элемента xsl:apply-templates: в этом элементе он устанавливает режим обработки. При выполнении xsl:apply-templates процессор будет применять только те шаблоны преобразования, режим которых совпадает с выбранным режимом обработки.
ПримерВ качестве примера приведем преобразование, которое добавляет в XHTML-файл перечень текстовых ссылок, обнаруженных в этом документе. Грубо говоря, XHTML — это XML-версия языка HTML, а значит XSLT вполне подходит для обработки XHTML-документов.
URI пространства имен языка XHTML — "http://www.w3.org/1999/xhtml"; этому языку мы назначим префикс "xhtml" и, кроме того, сделаем это пространство пространством имен по умолчанию:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml">
...
</xsl:stylesheet>
Начнем с шаблона, который будет выводить каждую из ссылок. В каждой ссылке мы будем выводить только ее атрибут href и текст, который она содержит. Для удобочитаемости мы также добавим элемент br и символ переноса строки 
.
<xsl:template match="xhtml:a">
<xsl:copy>
<xsl:copy-of select="@href|text()"/>
</xsl:copy>
<br/>
<xsl:text>
</xsl:text>
</xsl:template>
Мы чуть позже познакомимся с элементами xsl:copy, xsl:copy-of и xsl:text, пока же скажем, что
<xsl:copy>
<xsl:copy-of select="@href|text()"/>
</xsl:copy>
копирует в выходящий документ текущий узел, его атрибут href (@href) и дочерние текстовые узлы (text()).
Элемент <xsl:text>
</xsl:text> выводит символ переноса строки. Элемент <br/> является литеральным элементом результата — он никак не обрабатывается, а просто выводится в результирующий документ.
Следующее преобразование называется идентичным преобразованием — оно просто копирует все узлы один в один:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
И, наконец, нам понадобится преобразование для элемента body — в него мы включим копию содержимого, а также ссылки, отсортированные в алфавитном порядке:
<xsl:template match="xhtml:body">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<h1>Links found on this page:<h1>
<xsl:apply-templates
select=".//xhtml:a[@href and not(xhtml:*)]">
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
Если мы попытаемся выполнить преобразование, состоящее из этих шаблонов, мы обнаружим, что в тексте самого документа ссылки испортились — там тоже добавились элементы br и переносы строк. Это произошло потому, что шаблон для обработки ссылок имеет больший приоритет, чем шаблон, копирующий содержимое документа.
Для исправления этой ошибки мы выделим шаблон обработки ссылок в отдельный режим links:
<xsl:template match="xhtml:a" mode="links">
...
</xsl:template>
Теперь это правило не будет применяться к ссылкам во время копирования содержимого документа, потому что при выполнении инструкции
<xsl:apply-templates select="@*|node()"/>