Потоковая обработка 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 — это XbelReader в Примере закладок потока XML, который оборачивает 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() == "xbel" && xml.attributes().value("version") == "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 из Примера закладок потока XML оборачивает QXmlStreamWriter. Его функция writeFile() иллюстрирует основные функции QXmlStreamWriter, упомянутые выше:
bool XbelWriter::writeFile(QIODevice *device)
{
xml.setDevice(device);
xml.writeStartDocument();
xml.writeDTD("<!DOCTYPE xbel>");
xml.writeStartElement("xbel");
xml.writeAttribute("version", "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/qt-5.9/xml-streaming.html