Чтение онлайн

ЖАНРЫ

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

03 {

04 if (qName == "entry") {

05 currentItem = currentItem->parent;

06 } else if (qName == "page") {

07 if (currentItem) {

08 QString allPages = currentItem->text(1);

09 if (!allPages.isEmpty)

10 allPages += ", ";

11 allPages += currentText;

12 currentItem->setText(1, allPages);

13 }

14 }

15 return true;

16 }

Функция endElement вызывается

при обнаружении закрывающего тега. Так же как и для функции startElement, ее третий параметр содержит имя тега.

Если обнаружен тег </entry>, мы устанавливаем закрытую переменную currentItem на родительский элемент текущего элемента QTreeWidgetItem. Это обеспечивает восстановление переменной currentItem на значение, которое она имела перед чтением соответствующего тега <entry>.

Если обнаружен тег </page>, мы добавляем указанный номер страницы или диапазон страниц в разделяемый запятыми список в столбце 1 текущего элемента.

01 bool SaxHandler::fatalError(const QXmlParseException &exception)

02 {

03 QMessageBox::warning(0, QObject::tr("SAX Handler"),

04 QObject::tr("Parse error at line %1, column %2:\n%3.")

05 .arg(exception.lineNumber)

06 .arg(exception.columnNumber)

07 .arg(exception.message));

08 return false;

09 }

Функция fatalError вызывается, когда синтаксический анализ файла XML завершается неудачей. В этом случае мы просто выводим на экран сообщение, указывая номер строки, номер столбца и текст об ошибке синтаксического анализа.

Этим мы завершаем реализацию класса SaxHandler. Теперь давайте посмотрим, как можно использовать этот класс:

01 bool parseFile(const QString &fileName)

02 {

03 QStringList labels;

04 labels << QObject::tr("Terms") << QObject::tr("Pages");

05 QTreeWidget *treeWidget = new QTreeWidget;

06 treeWidget->setHeaderLabels(labels);

07 treeWidget->setWindowTitle(QObject::tr("SAX Handler"));

08 treeWidget->show;

09 QFile file(fileName);

10 QXmlInputSource inputSource(&file);

11 QXmlSimpleReader reader;

12 SaxHandler handler(treeWidget);

13 reader.setContentHandler(&handler);

14 reader.setErrorHandler(&handler);

15 return reader.parse(inputSource);

16 }

Мы задаем два столбца в виджете QTreeWidget. Затем мы создаем объект типа QFile для считываемого

файла и объект типа QXmlSimpleReader для синтаксического анализа файла. Нам не требуется самим открывать QFile; QXmlInputSource делает это автоматически.

Наконец, мы создаем объект типа SaxHandler, который используется для объекта reader одновременно в качестве обработчика содержимого файла и обработчика ошибок, и мы вызываем функцию parse для выполнения синтаксического анализа.

Вместо простого объекта файла мы передаем функции parse объект QXmlInputSource. Этот класс открывает заданный файл, читает его (учитывая кодировку символов в объявлении <?xml?>) и предоставляет интерфейс для чтения файла парсером.

В классе SaxHandler мы всего лишь переопределили функции, унаследованные от классов QXmlContentHandler и QXmlErrorHandler. Если бы мы стали переопределять функции других классов—обработчиков, нам пришлось бы вызывать соответствующие функции—установщики для объекта reader.

Для сборки приложения с библиотекой QtXml в файл .pro необходимо добавить следующую строку:

QT += xml

Чтение документов XML при помощи интерфейса DOM

DOM является стандартным программным интерфейсом синтаксического анализа документов XML, который разработан Консорциумом всемирной паутины (W3C). Qt обеспечивает уровень 2 интерфейса DOM для чтения, обработки и записи документов XML без проверки их достоверности.

DOM представляет файл XML в памяти в виде дерева. Мы можем просматривать дерево DOM столько раз, сколько нам нужно, и мы можем модифицировать и записывать его на диск в виде файла XML.

Давайте рассмотрим следующий документ XML:

<doc>

<quote>Ars longa vita brevis</quote>

<translation>Art is long, life is short</translation>

</doc>

Ему соответствует следующее дерево DOM:

Дерево DOM содержит узлы разных типов. Например, узел Element соответствует открывающему тегу и связанному с ним закрывающему тегу. Все, что располагается между этими тегами, представляется в виде дочерних узлов данного элемента Element.

В Qt различные типы таких узлов (как и все другие связанные с DOM классы) имеют префикс QDom. Так, QDomElement представляет узел Element, a QDomText представляет узел Text.

Различные узлы могут иметь дочерние узлы разных типов. Например, узел Element может содержать другие узлы Element, а также узлы EntityReference, Text, CDATASection, ProcessingInstruction и Comment. Рис. 15.3 показывает, какие типы дочерних узлов допустимы для соответствующих родительских узлов. Узлы, показанные серым, не могут иметь дочерних узлов.

Поделиться с друзьями: