Чтение онлайн

ЖАНРЫ

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

<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 << "\n";

}

// Компилировать таблицу стилей.

XSLTInputSource xsl("animals.xsl");

XalanCompiledStylesheet* compiledXsl = 0;

if (xslt.compileStylesheet(xsl, compiledXsl) != 0) {

cout << "xml error: " << xslt.getLastError << "\n";

}

// Выполнить преобразование.

if (xslt.transform(xml, xsl, html)) {

cout << "xml error: " << xslt.getLastFrror << "\n";

}

 } catch (const XMLException& e) {

cout << "xml error: " << toNative(e.getMessage) << "\n";

return EXIT_FAILURE;

 } catch (const exception& e) {

cout << e.what << "\n";

return EXIT_FAILURE;

 }

}

Смотри также

Рецепт 14.8.

14.8. Вычисление XPath-выражения

Проблема

Требуется извлечь информацию из документа XML, обработанного парсером, путем вычисления XPath-выражения.

Решение

Используйте библиотеку Xalan. Во-первых, выполните синтаксический анализ документа XML и получите указатель на

xalanc::XalanDocument
. Это можно сделать, используя экземпляры
XalanSourceTreeInit
,
XalanSourceTreeDOMSupport
и
XalanSourceTreeParserLiaison
, каждый из которых следующим образом определяется в пространстве имен
xalanc
.

#include <xercesc/framework/LocalFileInputSource.hpp>

#include <xalanc/XalanSourceTree/XalarSourceTreeDOMSupport.hpp>

#include <xalanc/XalanSourceTree/XalanSourceTreeInit.hpp>

#include <xalanc/XalanSourceTree/XalanSourceTreeParserLiaison.hpp>

...

int main {

 ...

 // Инициализировать подсистему XalanSourceTree

 XalarSourceTreeInit init;

 XalanSourceTreeDOMSupport support;

 // Интерфейс доступа к парсеру

 XalanSourceTreeParserLiaison liaison(support);

 // Подключить DOMSupport к ParserLiaison

 support.setParserLiaison(&liaison);

 LocalFileInputSource src(место-расположения-документа);

 XalanDocument* doc = liaison.ParseXMLStream(doc);

 ...

Поделиться с друзьями: