В этом случае парсер вызовет следующие обработчики событий синтаксического анализа:
startDocument
startElement("doc")
startElement("quote")
characters("Ars longa vita brevis")
endElement("quote")
endElement("doc")
endDocument
Все приведенные выше функции объявлены в классе QXmlContentHandler. Для простоты мы не стали указывать некоторые аргументы функций startElement и endElement.
QXmlContentHandler — это всего лишь один из многих классов—обработчиков, которые могут использоваться совместно с классом QXmlSimpleReader. Другими такими классами являются QXmlEntityResolver, QXmlDTDHandler, QXmlErrorHandler, QXmlDeclHandler и QXmlLexicalHandler. Эти классы только объявляют чистые виртуальные функции и предоставляют информацию о различных событиях синтаксического анализа. Для большинства приложений вполне достаточно использовать лишь классы QXmlContentHandler и QXmlErrorHandler.
Для удобства Qt также предоставляет класс QXmlDefaultHandler, который наследует все классы—обработчики и обеспечивает очень простую реализацию всех функций. Такая конструкция со множеством абстрактных классов—обработчиков и одним подклассом с тривиальной реализацией функций необычна для Qt; она принята для максимального соответствия модели Java—реализации.
Теперь мы рассмотрим пример, который показывает способы применения QXmlSimpleReader и QXmlDefaultHandler для синтаксического анализа файла XML заранее известного формата и для отображения его содержимого в виджете QTreeWidget. Подкласс QXmlDefaultHandler имеет название SaxHandler, и он используется для обработки предметного указателя книги, который содержит элементы и подэлементы.
Рис. 15.1. Дерево наследования для SaxHandler.
Ниже приводится файл предметного указателя книги, который отображается в виджете QTreeWidget и показан на рис. 15.2:
10
34-35
307-308
115
244
9
Рис. 15.2. Файл предметного указателя книги, загруженный в виджет QTreeWidget.
Первый этап в реализации парсера заключается в создании подкласса QXmlDefaultHandler:
01 class SaxHandler : public QXmlDefaultHandler
02 {
03 public:
04 SaxHandler(QTreeWidget *tree);
05 bool startElement(const QString &namespaceURI,
06 const QString &localName,
07 const QString &qName,
08 const QXmlAttributes &attributes);
09 bool endElement(const QString &namespaceURI,
10 const QString &localName,
11 const QString &qName);
12 bool characters(const QString &str);
13 bool fatalError(const QXmlParseException &exception);
14 private:
15 QTreeWidget *treeWidget;
16 QTreeWidgetItem *currentItem;
17 QString currentText;
18 };
Класс SaxHandler наследует QXmlDefaultHandler и переопределяет четыре функции: startElement, endElement, characters и fatalError. Первые четыре функции объявлены в QXmlContentHandler; последняя функция объявлена в QXmlErrorHandler.
01 SaxHandler::SaxHandler(QTreeWidget *tree)
02 {
03 treeWidget = tree;
04 currentItem = 0;
05 }
Конструктор SaxHandler принимает объект типа QTreeWidget, который мы собираемся заполнять информацией, содержащейся в файле XML.
01 bool SaxHandler::startElement(const QString & /* namespaceURI */,
02 const QString & /* localName */,
03 const QString &qName,
04 const QXmlAttributes &attributes)
05 {
06 if (qName == "entry") {
07 if (currentItem) {