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 —
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 с возможностями
К счастью, библиотека Pathan реализует XPath, совместимый с Xerces и позволяющий легко манипулировать Xerces DOM. Пример 14.24 показывает, как можно использовать Pathan для определения места расположения и удаления узла слона Herby из документа XML, приведенного в примере 14.1, с помощью вычисления XPath-выражения animalList/animal[child::name='Herby']
. Сравнение этого примера с примером 14.10 ясно показывает, насколько мощным является язык XPath.
#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;
/*