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

ЖАНРЫ

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

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

Шрифт:

XObjectPtr result =

evaluator.evaluate(

support, // поддержка DOM

xalanDoc, // контекстный узел

xpath.c_str, // XPath-выражение

resolver); // функция разрешения пространства имен

const NodeRefListBase& nodeset = result->nodeset;

// Просмотр списка узлов и вывод имен животных

for (size_t i = 0, len = nodeset.getLength; i < len; ++i) {

const XMLCh* name = nodeset.item(i)->getNodeValue.c_str;

std::cout << toNative(name) << "\n";

}

 } catch (const DOMException& e) {

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

return EXIT_FAILURE;

 } catch (const exception& e) {

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

return EXIT_FAILURE;

 }

}

Обсуждение

XPath —

это язык поиска по образцу (pattern matching language), предназначенный для извлечения информации из документов XML. Основная конструкция XPath — выражение пути (path expression) поддерживает иерархический синтаксис ссылок на элементы, атрибуты и текстовые узлы на основе использования их имен, атрибутов, текстового содержимого, отношений наследования и других свойств. Кроме работы с наборами узлов язык XPath может обрабатывать строки, числа и булевы значения. XPath версии 2.0, которая в настоящее время не поддерживается библиотекой Xalan, использует даже более сложную модель данных, основанную на рекомендациях XML Schema. (См. рецепт 14.5.)

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

parent
,
child
и
descendant
. В примере 14.23 я указал корень (
root
) документа XML в качестве контекстного узла; этот узел является родительским по отношению к корневому элементу документа XML, а также к любой инструкции обработки и комментариям верхнего уровня. При вычислении выражения с использованием корневого узла в качестве контекстного узла выражение пути
animalList/animal/name/child::text
соответствует всем текстовым узлам, дочерним по отношению к элементам name, родительским элементом которых является
animal
, и чьим «дедушкой» является элемент
animalList
.

Метод

evaluate
класса
XPathEvaluator
возвращает
XObjectPtr
, представляющий результат вычисления выражения XPath. Тип данных, на который ссылается
XObjectPtr
, можно узнать путем его разыменования с получением
XObject
и вызова метода
getType
; затем можно получить доступ к базовым данным при помощи вызова
num
,
boolean
,
str
или
nodeset
. Поскольку XPath-выражение в примере 14.23 представляет набор узлов, я использовал метод
nodeset
для получения ссылки на
NodeRefListBase
, который обеспечивает доступ к узлам в наборе с помощью его методов
getLength
и
item
. Метод
item
возвращает указатель на узел
XalanNode
, метод
getNodeValue
которого возвращает строку с интерфейсом, похожим на интерфейс
std::basic_string
.

Поскольку XPath обеспечивает простой способ определения местоположения

узлов в документе XML, возникает естественный вопрос о возможности применения выражений Xalan XPath для получения экземпляров
xercesc::DOMNode
из
xercesc::DOMDocument
. На самом деле это возможно, но не совсем удобно, а кроме того, по умолчанию узлы
xercesc::DOMNodes
, полученные таким способом, представляют дерево документа XML с возможностями только чтения, что уменьшает пользу от применения XPath в качестве средства манипулирования DOM. Существуют способы, позволяющие обойти это ограничение, однако они достаточно сложны и потенциально опасны.

К счастью, библиотека Pathan реализует XPath, совместимый с Xerces и позволяющий легко манипулировать Xerces DOM. Пример 14.24 показывает, как можно использовать Pathan для определения места расположения и удаления узла слона Herby из документа XML, приведенного в примере 14.1, с помощью вычисления XPath-выражения

animalList/animal[child::name='Herby']
. Сравнение этого примера с примером 14.10 ясно показывает, насколько мощным является язык XPath.

Пример 14.24. Определение местоположения узла и удаление его с использованием библиотеки Pathan

#include <exception>

#include <iostream> // cout

#include <xercesc/dom/DOM.hpp>

#include <xercesc/framework/LocalFileFormatTarget.hpp>

#include <xercesc/util/PlatformUtils.hpp>

#include <pathan/XPathNamespace.hpp>

#include <pathan/XPathResult.hpp>

<include <pathan/XPathEvaluator.hpp>

#include <pathan/XPathExpression.hpp>

#include "xerces_strings.hpp" // Пример 14.4

using namespace std;

using namespace xercesc;

/*

 * Определить XercesInitializer, как это сделано в примере 14.8, а также

 * CircusFrrorHandler и DOMPtr, как это сделано в примере 14.10

 */

int main {

 try {

// Инициализировать Xerces и получить DOMImplementation.

XercesInitializer init;

DOMImplementation* impl =

DOMImplementationRegistry::getDOMImplementation(

fromNative("LS").c_str

);

if (impl == 0) {

cout << "couldn't create DOM implementation\n";

return EXIT_FAILURE;

}

// Сконструировать DOMBuilder для синтаксического анализа

// документа animals.xml.

DOMPtr<DOMBuilder> parser =

static cast<DOMImplementationLS*>(impl)-> createDOMBuilder(

DOMImplementationLS::MODE_SYNCHRONOUS, 0

);

CircusErrorHandler err;

parser->setErrorHandler(&err);

// Выполнить синтаксический анализ

animals.xml. DOMDocument* doc =

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