XPathInitializer init;

  XercesDOMParser parser;

  // Зарегистрировать обработчик ошибок

  CircusErrorHandler error;

  parser.setErrorHandler(&error);

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

  parser.parse(fromNative('animals.xml').c_str());

  DOMDocument* doc = parser.getDocument();

  DOMElement* animalList = doc->getDocumentElement();

  // Создать XalanDocument на основе doc.

  XercesDOMSupport support;

  XercesParserLiaison liaison(support);

  XercesDOMWrapperParsedSource src(doc, liaison, support);

  XalanDocument* xalanDoc = src.getDocument();

  // Вычислить XPath-выражение для получения списка

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

  XPathEvaluator evaluator;

  XalanDocumentPrefixResolver resolver(xalanDoc);

  XercesString xpath =

   fromNative('animalList/animal/name/child::text()');

  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) << ' ';

  }

 } catch (const DOMException& e) {

  cout << 'xml error: ' << toNative(e.getMessage()) << ' ';

  return EXIT_FAILURE;

 } catch (const exception& e) {

  cout << e.what() << ' ';

  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;

/*

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату