Используйте реализацию Xerces в виде программного интерфейса SAX2 (простой программный интерфейс для XML, версия 2.0). Во-первых, создайте класс, производный от xercesc::ContentHandler; этот класс будет получать уведомления с информацией о структуре и содержимом вашего документа XML по мере его анализа. Затем при желании можно создать класс, производный от xercesc::ErrorHandler, для получения предупреждений и сообщений об ошибках. Сконструируйте парсер типа xercesc::SAX2XMLReader, зарегистрируйте экземпляры классов вашего обработчика, используя методы парсера setContentHandler() и setErrorHandler(). Наконец, вызовите метод парсера parse(), передавая в качестве аргумента полное имя файла, в котором содержится ваш документ.

Например, пусть требуется выполнить синтаксический анализ документа XML animals.xml, приведенного в примере 14.1, и сконструировать вектор std::vector объектов Animal, представляющих животных, перечисленных в этом документе. (Определение класса Animal дается в примере 14.2.) В примере 14.3 я показываю, как можно это сделать, используя TinyXml. Для усложнения задачи добавим в документ пространства имен, как показано в примере 14.5.

Пример 14.5. Список цирковых животных, в котором используются пространства имен XML

 

  Herby

  elephant

  1992-04-23

 

 

 

 

Для анализа этого документа с помощью SAX2 определите ContentHandler, как показано в примере 14.6, и ErrorHandler, как показано в примере 14.7. Затем сконструируйте SAX2XMLReader, зарегистрируйте ваши обработчики и запустите парсер. Это проиллюстрировано в примере 14.8.

Пример 14.6. Применение SAX2 ContentHandler для синтаксического анализа документа animals.xml

#include // runtime_error

#include

#include

#include // Содержит реализации без

                                           // операций для различных

                                           // обработчиков, используемых

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

#include "animal.hpp"

using namespace std;

using namespace xercesc;

// Возвращает экземпляр Contact, построенный

// на основе заданного набора атрибутов

Contact contactFromAttributes(const Attributes &attrs) {

 // Для повышения эффективности хранить часто используемые строки

 // в статических переменных

 static XercesString name = fromNative("name");

 static XercesString phone = fromNative("phone");

 Contact result;   // Возвращаемый объект Contact.

 const XMLCh* val; // Значение атрибута name или phone.

 // Установить имя объекта Contact.

 if ((val = attrs.getValue(name.c_str())) != 0) {

  result.setName(toNative(val));

 } else {

  throw runtime_error("contact missing name attribute");

 }

 // Установить номер телефона для объекта Contact.

 if ((val = attrs.getValue(phone.c_str())) != 0) {

  result.setPhone(toNative(val));

 } else {

  throw runtime_error("contact missing phone attribute");

 }

 return result;

}

// Реализует обратные вызовы, которые получают символьные данные и

// уведомления о начале и конце элементов

class CircusContentHandler : public DefaultHandler {

public:

 CircusContentHandler(vector& animalList) :

  animalList_(animalList) {}

 // Если текущий элемент представляет ветеринара или дрессировщика

 // используйте attrs для конструирования объекта Contact для текущего

 // Animal; в противном случае очистите currentText_, подготавливая

Перейти на страницу:

Похожие книги