14.7. Преобразование документа XML с помощью XSLT
14.7. Преобразование документа XML с помощью XSLT
Проблема
Требуется преобразовать документ XML, используя таблицу стилей XSLT.
Решение
Используйте библиотеку Xalan. Во-первых, сконструируйте экземпляр конвертора XSTL xalanc::XalanTransformer. Затем сконструируйте два экземпляра xalanc::XSLTInputSource (один для документа, который будет преобразован, а другой для вашей таблицы стилей) и экземпляр хаlanc::XSLTResultTarget для документа, который будет получен в результате преобразования. Наконец, вызовите метод XSLT transform(), передавая в качестве аргументов два экземпляра XSLTInputSource и один XSLTResultTarget.
Например, представим, что требуется с помощью веб-браузера просматривать список животных цирка из примера 14.1. Это легко сделать с помощью XSLT В примере 14.19 приводится таблица стилей XSLT, которая на входе принимает документ XML, такой как animals.xml, и формирует документ HTML, содержащий таблицу, в каждой строке которой описывается одно животное с указанием клички, вида, даты рождения, ветеринара и дрессировщика. Пример 14.20 показывает, как можно использовать библиотеку Xalan, чтобы воспользоваться этой таблицей стилей для документа animals.xml. В примере 14.21 приводится HTML, сгенерированный программой из примера 14.20; этот HTML переформатирован для лучшего восприятия.
Пример 14.19. Таблица стилей для animals.xml
<?xml version="1.0" encoding="utf-8"?>
<!- Таблица стилей для животных цирка Feldman Family Circus -->
<xsl:stylesheet versions="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head>
<title>Feldman Family Circus Animals</title>
</head>
<body>
<h1>Feldman Family Circus Animals</h1>
<table cellpadding="3" border="1">
<tr>
<th>Name</th>
<th>Species</th>
<th>Date of Birth</th>
<th>Veterinarian</th>
<th>Trainer</th>
</tr>
<xsl:apply-templates match="animal">
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="animal">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="species"/></td>
<td><xsl:value-of select="dateOfBirth"/></td>
<xsl:apply-templates select="veterinarian"/>
<xsl:apply-templates select="trainer"/>
</tr>
</xsl:template>
<xsl:template match="veterinarian|trainer">
<td>
<table>
<tr>
<th>name:</th>
<td>
<xsl:value-of select="attribute::name"/>
</td>
</tr>
<tr>
<th>phone:</th>
<td><xsl:value of select="attribute::phone"/></td>
</tr>
</table>
</td>
</xsl:template>
</xsl:stylesheet>
Пример 14.20. Применение таблицы стилей animals.xsl для файла animals.xml с использованием библиотеки Xalan
#include <exception>
#include <iostream> // cout
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <xalanc/XalanTransformer/XalanTransformer.hpp>
#include <xalanc/XSLT/XSLTInputSource.hpp>
#include <xalanc/XSLT/XSLTResultTarget.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include "xerces_strings.hpp" // Пример 14.4
using namespace std;
using namespace xercesc;
using namespace xalanc;
// Утилита RAII, которая инициализирует парсер и освобождает ресурсы
// при выходе из области видимости
struct XalanInitializer {
XalanInitializer() {
XMLPlatformUtils::Initialize();
XalanTransformer::initialize();
}
~XalanInitializer() {
XalanTransformer::terminate();
XMLPlatformUtils::Terminate();
}
};
int main() {
try {
XalanInitializer init; // Инициализировать Xalan.
XalanTransformer xslt; // Конвертор XSLT.
XSLTInputSource xml("animals.xml"); // Документ XML из
// примера 14.1
XSLTInputSource xsl("animals.xsl"); // Таблица стилей из
// примера 14.19.
XSLTResultTarget html("animals.html"); // Результат выполнения xslt.
// Выполнить преобразование.
if (xslt.transform(xml, xsl, html) != 0) {
cout << "xml error: " << xslt.getLastError() << " ";
}
} catch (const XMLException& e) {
cout << "xml error " << toNative(e.getMessage()) << " ";
return EXIT_FAILURE;
} catch (const exception& e) {
cout << e.what() << " ";
return EXIT_FAILURE;
}
}
Пример 14.21. Документ HTML, сгенерированный программой из примера 14.20
<html>
<head>
<МЕТА http-equiv="Content Type" content="text/html; charset=UTF-8">
<title>Feldman Family Circus Animals</title>
</head>
<body>
<h1>Feldman Family Circus Animals</h1>
<table cellpadding="3" border="1">
<tr>
<th>Name</th>
<th>Species</th>
<th>Date of Birth</th>
<th>Veterinarian</th>
<th>Trainer</th>
</tr>
<tr>
<td>Herby</td>
<td>elephant</td>
<td>1992-04-23</td>
<td>
<table>
<tr><th>name:</th><td>Dr. Hal Brown</td></tr>
<tr><th>phone:</th><td>(801)595-9627</td></tr>
</table>
</td>
<td>
<table>
<tr><th>name:</th><td>Bob Fisk</td></tr>
<tr><th>phone:</th><td>(801)881-2260</td></tr>
</table>
</td>
</tr>
<tr>
<td>Sheldon</td>
<td>parrot</td>
<td>1998-09-30</td>
<td>
<table>
<tr><th>name:</th><td>Dr. Kevin Wilson</td></tr>
<tr><th>phone:</th><td>(801)466-6498</td></tr>
</table>
</td>
<td>
<table>
<tr><th>name:</th><td>Eli Wendel</td></tr>
<tr><th>phone:</th><td>(801)929-2506</td></tr>
</table>
</td>
</tr>
<tr>
<td>Dippy</td>
<td>penguin</td>
<td>2001-06-08</td>
<td>
<table>
<tr><th>name:</th><td>Dr. Barbara Swayne</td></tr>
<tr><th>phone:</th><td>(801)459-7746</td></tr>
</table>
</td>
<td>
<table>
<tr><th>name:</th><td>Ben Waxman</td></tr>
<tr><th>phone:</th><td>(801)882-3549</td></tr>
</table>
</td>
</tr>
</table>
</body>
</html>
Обсуждение
XSL-преобразование (стандарт XSLT) представляет собой язык преобразования документов XML в другие документы XML. XSLT является одним из элементов семейства спецификаций расширяемых языков описания таблиц стилей (Extensible Stylesheet Language — XSL), который обеспечивает базовые средства для визуального представления документов XML Однако XSLT полезен не только при форматировании; например, он используется веб-серверами при генерации HTML-документов «на лету» и такими системами генерации документов, как DocBook.
Преобразования XSLT представляются в виде документов XML, называемых таблицами стилей (stylesheets). Таблица стилей используется для обработки исходного документа и формирования выходного документа (result document). Таблица стилей состоит из набора шаблонов, которым соответствуют узлы исходного документа и которые применяются для получения фрагментов выходного документа. Шаблоны рекурсивно применяются к исходному документу, генерируя фрагменты выходного документа один за другим, пока не будет обнаружено ни одного соответствия. Условия соответствия записываются с помощью языка XPath, предназначенного для извлечения информационных строк, чисел, булевых значений и наборов узлов из документов XML.
Таблица стилей представленная в примере 14.19, состоит из трех шаблонов. В главном шаблоне атрибут match равен /, т.е. он соответствует корню исходною документа, а именно узлу, который является родительским узлом по отношению к корневому элементу документа и любым инструкциям обработки и комментариям верхнего уровня. При применении этого шаблона генерируется фрагмент документа HTML, содержащий заголовок «Животные цирка Feldman Family Circus» и таблицу с одной строкой, состоящей из пяти элементов th с метками Name, Species, Date of Birth, Veterinarian и trainer. Этот шаблон содержит элемент apply-templates, которому соответствует атрибут animal. Это приводит к тому, что второй шаблон таблицы стилей с атрибутом соответствия animal — будет применяться один раз к каждому элементу animal, дочернему по отношению к корневому документу, формируя строку таблицы для каждого дочернего элемента. Строка, сгенерированная для элемента animal, состоит из пяти элементов td. Первые три элемента td содержат текстовое значение дочерних элементов animal (name, species и dateOfBirth), извлекаемое с помощью инструкции XSLT value-of. Последние два элемента td содержат элементы таблицы, полученные путем применения третьего шаблона таблицы стилей с атрибутом соответствия veterinarian|trainer, применяемого к дочерним элементам животного veterinarian и trainer.
Хотя в примере 14.20 мною указаны локальные файлы для таблицы стилей, исходного документа и выходного документа, XSLTInputSources и XSLTResultTargets могут быть сконструированы из потоков стандартной библиотеки C++, позволяя XalanTransformer принимать поток ввода и генерировать результат в произвольном месте. Более того, вместо получения на входе экземпляров XSLTInputSource конвертор XalanTransformer может работать с предварительно скомпилированной таблицей стилей, представляющей экземпляр xalanc::XalanCompiledStylesheet, и с исходным документом, прошедшим обработку парсером и представленным экземпляром xalanc::XalanParsedSource. Это проиллюстрировано в примере 14.22. Если требуется применять одну таблицу стилей к нескольким исходным документам, гораздо более эффективный результат получается при использовании XalanCompiledStylesheet, чем XSLTInputSource.
Пример 14.22. Выполнение преобразования XSLT с применением предварительно откомпилированной таблицы стилей
/*
* те же операторы #include, которые использовались в примере 14.20
*/
using namespace std;
using namespace xercesc;
using namespace xalanc;
/*
* Определить XalanInitializer так же, как в примере 14.20
*/
int main() {
try {
XalanInitializer init; // Инициализировать Xalan
XalanTransformer xslt; // Конвертор XSLT.
XSLTResultTarget html("animals.html"); // Результат работы xslt.
// Выполнить синтаксический анализ исходного документа
XSLTInputSource xml("animals.xml");
XalanParsedSource* parsedXml = 0;
if (xslt.parseSource(xml, parsedXml) != 0) {
cout << "xml error: " << xslt.getLastError() << " ";
}
// Компилировать таблицу стилей.
XSLTInputSource xsl("animals.xsl");
XalanCompiledStylesheet* compiledXsl = 0;
if (xslt.compileStylesheet(xsl, compiledXsl) != 0) {
cout << "xml error: " << xslt.getLastError() << " ";
}
// Выполнить преобразование.
if (xslt.transform(xml, xsl, html)) {
cout << "xml error: " << xslt.getLastFrror() << " ";
}
} catch (const XMLException& e) {
cout << "xml error: " << toNative(e.getMessage()) << " ";
return EXIT_FAILURE;
} catch (const exception& e) {
cout << e.what() << " ";
return EXIT_FAILURE;
}
}
Смотри также
Рецепт 14.8.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
XSL = XSLT + XSL-FO
XSL = XSLT + XSL-FO Сам XSLT в действительности является частью более крупной спецификации — расширенного языка таблиц стилей, Extensible Stylesheet Language, или XSL. XSL предназначен для задания точного, до миллиметра, формата документов. Форматирующая часть XSL, представляющая гораздо более
Преобразования XSLT-XSL
Преобразования XSLT-XSL XSLT позволяет работать непосредственно с содержимым документов XML. Например, у вас может быть огромный документ XML, содержащий всю бейсбольную статистику за последний сезон, однако вас может интересовать только статистика для питчеров. Чтобы извлечь
Версии XSLT
Версии XSLT Спецификации XSLT разрабатывались значительно активнее, чем спецификации для всего XSL. Рекомендация XSLT 1.0 была окончательно принята 16 ноября 1999 г., и эта версия является сегодня основной версией XSLT.Затем появился рабочий проект XSLT 1.1 и, хотя первоначально он
Преобразование документа в представление с форматирующими объектами
Преобразование документа в представление с форматирующими объектами Для того чтобы преобразовать planets.xml в документ, использующий форматирующие объекты, который я назвал planets.fo, достаточно всего лишь применить таблицу стилей planetsPDF.xsl. Это можно сделать при помощи техник
Функции XSLT
Функции XSLT В следующем списке перечислены встроенные в XSLT функции:• current(). Возвращает текущий (current) узел — но не контекстный узел. Текущий узел — это узел, используемый в данный момент в таких циклах, как <xsl:for-each>. Функцию current нельзя применять в образцах;• document().
Преобразование в XSL-FO при помощи таблицы стилей XSLT
Преобразование в XSL-FO при помощи таблицы стилей XSLT В этой главе я создам таблицу стилей для преобразования planets.xml в planets.fo. Я буду создавать таблицу шаг за шагом; для справки я приведу ее окончательный вид (листинг 11.2).Листинг 11.2. planets.xsl<?xml
R.12.3.1 Преобразование с помощью конструктора
R.12.3.1 Преобразование с помощью конструктора Конструктор, имеющий единственный параметр, задает преобразование типа своего фактического параметра в тип его класса, например:class X { //…public: X(int); X(const char*, int = 0);};void f(X arg) { X a = 1; // a = X(1); X b = "Jessie"; // b = X("Jessie",0) a = 2; // a = X(2) f(3); //
Масштабирование документа с помощью программного кода
Масштабирование документа с помощью программного кода Для управления параметрами увеличения документа вам необходимо немного углубиться в иерархию объектов, чтобы добраться до объекта Zoom, а затем изменить значение его свойства Percentage. Соответствующий пример приведен
Создание нового документа с помощью окна начала работы
Создание нового документа с помощью окна начала работы Чтобы при создании нового файла использовалось окно начала работы, необходимо присвоить значение 1 системной переменной STARTUP. Для этого выполните следующие действия.1. Введите в командную строку название переменной
Оформление документа с помощью подложки
Оформление документа с помощью подложки В процессе работы с документом иногда возникает необходимость придать ему такой вид, чтобы те, кто будет впоследствии его читать, быстро и правильно поняли предназначение и особенности данного документа. Например, документ может
Создание нового документа с помощью окна начала работы
Создание нового документа с помощью окна начала работы Чтобы при создании нового файла использовалось окно начала работы, необходимо присвоить значение 1 системной переменной STARTUP. Для этого выполните следующие действия.1. Введите в командную строку название переменной
Отличия XSLT 1.1 от XSLT 1.0
Отличия XSLT 1.1 от XSLT 1.0 Отсутствие result tree fragment Главное и наиболее существенное отличие XSLT 1.1 от XSLT 1.0 состоит в том, что тип данных, известный в XSLT 1.0 как result tree fragment (результирующий фрагмент дерева) в XSLT 1.1. отсутствует. Вместо него в версии 1.1 используется множество узлов,
Отличия XSLT 2.0 от XSLT 1.1
Отличия XSLT 2.0 от XSLT 1.1 Прежде чем приступить к описанию отличий второй версии XSLT от версии 1.1 (и, соответственно, 1.0), следует сделать одно существенное замечание. Лицензионные соглашения Консорциума W3 не позволяют раскрывать широкой общественности внутренние материалы
Преобразование формы в отчет и страницу доступа к данным с помощью диалогового окна Сохранение
Преобразование формы в отчет и страницу доступа к данным с помощью диалогового окна Сохранение В завершение главы, посвященной созданию форм и работе с ними, покажем еще одну возможность использования формы – преобразование и сохранение в виде отчета или страницы
Практическая работа 34. Форматирование документа с помощью стилей
Практическая работа 34. Форматирование документа с помощью стилей Задание. Создать документ по приведенному образцу (рис. 5.46). Отформатировать его с помощью встроенных стилей.Последовательность выполнения1. Создайте новый документ и наберите предлагаемый текст без