Потоковая обработка XML
Начиная с версии 4.3, Qt предоставляет два новых класса для чтения и записи XML: QXmlStreamReader и QXmlStreamWriter.
Классы QXmlStreamReader и QXmlStreamWriter являются новыми классами, предоставленными в Qt 4.3 и более поздних версиях. Потоковый читатель сообщает об XML-документе как о потоке маркеров. Это отличается от SAX, так как приложения SAX предоставляют обработчики для получения XML-событий от анализатора, тогда как QXmlStreamReader управляет циклом, извлекая маркеры из читателя по мере необходимости. Такой подход с извлечением позволяет создавать парсеры с рекурсивным спуском, позволяя код парсинга XML разбивать на разные методы или классы.
QXmlStreamReader — это валидирующий XML 1.0-парсер, который исключает внешние анализируемые сущности. Следовательно, данные, предоставляемые потоковым читателем, соответствуют критериям W3C для валидного XML, пока не произойдёт ошибка. В противном случае, можно использовать такие функции, как atEnd(), error() и hasError(), для проверки и просмотра ошибок.
Пример реализации QXmlStreamReader представлен в примере QXmlStream Bookmarks, который оборачивает QXmlStreamReader. Конструктор принимает treeWidget в качестве параметра, и класс имеет специфичные для Xbel функции:
XbelReader(QTreeWidget *treeWidget);
...
void readXBEL();
void readTitle(QTreeWidgetItem *item);
void readSeparator(QTreeWidgetItem *item);
void readFolder(QTreeWidgetItem *item);
void readBookmark(QTreeWidgetItem *item);
QTreeWidgetItem *createChildItem(QTreeWidgetItem *item);
QXmlStreamReader xml;
QTreeWidget *treeWidget;
...Функция read() принимает QIODevice и устанавливает его с помощью setDevice(). Функция raiseError() используется для отображения пользовательского сообщения об ошибке, указывающего на то, что версия файла неверна.
bool XbelReader::read(QIODevice *device)
{
xml.setDevice(device);
if (xml.readNextStartElement()) {
if (xml.name() == QLatin1String("xbel")
&& xml.attributes().value(versionAttribute()) == QLatin1String("1.0")) {
readXBEL();
} else {
xml.raiseError(QObject::tr("The file is not an XBEL version 1.0 file."));
}
}
return !xml.error();
}Дополнительный класс к QXmlStreamReader — QXmlStreamWriter, который предоставляет XML-писатель с простым потоковым API. QXmlStreamWriter работает с QIODevice и имеет специализированные функции для всех XML-маркеров или событий, которые вы хотите записать, такие как writeDTD(), writeCharacters(), writeComment() и так далее.
Для записи XML-документа с помощью QXmlStreamWriter, вы начинаете документ с функцией writeStartDocument() и завершаете его с writeEndDocument(), которая неявно закрывает все оставшиеся открытые теги. Теги элементов открываются с помощью writeStartDocument() и следуют за writeAttribute() или writeAttributes(), содержимое элемента, и затем writeEndDocument(). Также, можно использовать writeEmptyElement() для записи пустых элементов.
Содержимое элемента включает символы, ссылки на сущности или вложенные элементы. Содержимое можно записать с помощью writeCharacters(), функция, которая также обрабатывает экранирование всех запрещённых символов и последовательностей символов, writeEntityReference(), или последующие вызовы writeStartElement().
Класс XbelWriter из QXmlStream Bookmarks Example оборачивает QXmlStreamWriter. Его функция writeFile() демонстрирует основные функции QXmlStreamWriter, упомянутые выше:
bool XbelWriter::writeFile(QIODevice *device)
{
xml.setDevice(device);
xml.writeStartDocument();
xml.writeDTD(QStringLiteral("<!DOCTYPE xbel>"));
xml.writeStartElement(QStringLiteral("xbel"));
xml.writeAttribute(XbelReader::versionAttribute(), QStringLiteral("1.0"));
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i)
writeItem(treeWidget->topLevelItem(i));
xml.writeEndDocument();
return true;
}
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/xml-streaming.html