Spec-Zone.ru › Qt 5.15

Потоковая обработка XML

Qt предоставляет два класса для чтения и записи XML с помощью простого потокового API: QXmlStreamReader и QXmlStreamWriter.

Потоковый читатель сообщает об 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() == 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 из Примера закладок XML-потока оборачивает 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/qt-5.15/xml-streaming.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API