Таблица стилей состоит из набора шаблонов, которым соответствуют узлы исходного документа и которые
Таблица стилей представленная в примере 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
.
/*
* те же операторы #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.
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>
...