XML - статьи



              

CSaxHandler – класс обработчиков SAX-анализатора - часть 2


// csaxhandler.cpp

#include "csaxhandler.h" #include "cnode.h"

//----------------------------------------------------------------------

CSaxHandler::CSaxHandler(){ reset(); }

CSaxHandler::CSaxHandler(CNode* node){ setDocument(node); }

CSaxHandler::~CSaxHandler(){ // doc не удаляем (владелец - внешняя программа)! textElement.clear(); nodeStack.clear(); }

void CSaxHandler::reset(){ doc=0; textElement.clear(); nodeStack.clear(); }

void CSaxHandler::setDocument(CNode* node){ reset(); doc=node;

// корневой элемент nodeStack.push(doc); } //----------------------------------------------------------------------

bool CSaxHandler::startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &attributes){

if(nodeStack.isEmpty()) return false;

// текущий элемент CNode* node=nodeStack.top();

// обрабатываемый элемент if(node) node=node->getNode(localName);

// инициализация реквизитов if(node) node->setRequisites(localName,attributes);

// сделаем его текущим nodeStack.push(node); textElement.clear(); return true; } //----------------------------------------------------------------------

bool CSaxHandler::characters(const QString &str){ textElement+=str; return true; } //----------------------------------------------------------------------

bool CSaxHandler::endElement(const QString &namespaceURI, const QString &localName, const QString &qName){ if(nodeStack.isEmpty()) return false;

CNode* node=nodeStack.top();

// инициализация текстовых элементов if(node && node->isTextElement(localName)){ QXmlAttributes textAttr; textAttr.append(localName,"","",textElement); node->setRequisites(localName,textAttr); }

// элемент обработан nodeStack.pop(); return true; } //----------------------------------------------------------------------

Реквизиты объекта, соответствующие атрибутам исходного документа, инициализируются в обработчике startElement(), реквизиты, соответствующие символьным данным, – в endElement(). Для инициализации используется один и тот же метод интерфейсного класса setRequisites(). Для этого значение текстового элемента записывается в объект класса QXmlAttributes, используемого для передачи атрибутов.

Это искусственный прием, позволяющий сэкономить один метод в интерфейсе CNode. Правда, при этом немного усложняется реализация setRequisites() в узловых классах, поскольку в нем появляется дополнительный условный оператор. Альтернатива – добавление в интерфейс метода инициализации только текстовых реквизитов. Что лучше – судите сами. Автору представляется, что его вариант более экономный.

Собственно, этими двумя классами и ограничивается реализация общего подхода для разбора произвольных XML-документов. Как ими пользоваться – в следующем разделе на примере конкретного документа.




Содержание  Назад  Вперед