Qt 处理 XML 数据

在 Qt 中,处理 XML 数据通常使用 Qt 提供的 QDomDocument、QXmlStreamReader 和 QXmlStreamWriter 类。这些类可以帮助你读取、修改和写入 XML 数据。

1. 使用 QDomDocument 处理 XML

QDomDocument 提供了对 XML 文档的 DOM(Document Object Model)结构的访问方式。这是一种树形结构,适用于对 XML 进行修改。

1.1. 读取 XML 文件

cpp 复制代码
#include <QDomDocument>
#include <QFile>
#include <QDebug>

void readXml() {
    QFile file("example.xml");  // 打开 XML 文件
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open file!";
        return;
    }

    QDomDocument doc;
    if (!doc.setContent(&file)) {  // 设置文档内容
        qDebug() << "Failed to parse XML!";
        file.close();
        return;
    }
    
    file.close();

    // 获取根元素
    QDomElement root = doc.documentElement();
    qDebug() << "Root Element:" << root.tagName();

    // 遍历子元素
    QDomNodeList nodes = root.elementsByTagName("item");  // 假设有多个 <item> 元素
    for (int i = 0; i < nodes.count(); ++i) {
        QDomElement element = nodes.at(i).toElement();
        if (!element.isNull()) {
            qDebug() << "Item name:" << element.attribute("name");
            qDebug() << "Item value:" << element.text();
        }
    }
}

1.2. 创建或修改 XML 文件

cpp 复制代码
#include <QDomDocument>
#include <QFile>
#include <QTextStream>
#include <QDebug>

void writeXml() {
    QDomDocument doc;

    // 创建根元素
    QDomElement root = doc.createElement("root");
    doc.appendChild(root);

    // 创建一个子元素 <item>
    QDomElement item = doc.createElement("item");
    item.setAttribute("name", "item1");  // 设置属性
    item.appendChild(doc.createTextNode("This is item 1"));  // 设置内容
    root.appendChild(item);

    // 创建第二个子元素 <item>
    item = doc.createElement("item");
    item.setAttribute("name", "item2");
    item.appendChild(doc.createTextNode("This is item 2"));
    root.appendChild(item);

    // 将 XML 写入文件
    QFile file("output.xml");
    if (!file.open(QIODevice::WriteOnly)) {
        qDebug() << "Failed to open file for writing!";
        return;
    }

    QTextStream stream(&file);
    doc.save(stream, 4);  // 将文档保存到文件中,4 是缩进的空格数
    file.close();
}

1.3. 修改 XML 文件

cpp 复制代码
void modifyXml() {
    QFile file("example.xml");
    if (!file.open(QIODevice::ReadWrite)) {
        qDebug() << "Failed to open file!";
        return;
    }

    QDomDocument doc;
    if (!doc.setContent(&file)) {
        qDebug() << "Failed to parse XML!";
        file.close();
        return;
    }

    file.close();

    // 获取根元素
    QDomElement root = doc.documentElement();

    // 修改第一个 <item> 元素的内容
    QDomNodeList nodes = root.elementsByTagName("item");
    if (!nodes.isEmpty()) {
        QDomElement element = nodes.at(0).toElement();
        element.firstChild().setNodeValue("Updated item content");

        // 将修改后的内容保存回文件
        if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
            QTextStream stream(&file);
            doc.save(stream, 4);
            file.close();
        }
    }
}

2. 使用 QXmlStreamReader 解析 XML

QXmlStreamReader 是基于事件的流解析器,适合用于逐个读取和处理大型 XML 文件。它是基于流的,不会将整个文件加载到内存中,因此适用于处理大型文件。

2.1. 读取 XML 数据

cpp 复制代码
#include <QXmlStreamReader>
#include <QFile>
#include <QDebug>

void readXmlStream() {
    QFile file("example.xml");
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open file!";
        return;
    }

    QXmlStreamReader xml(&file);

    while (!xml.atEnd()) {
        xml.readNext();
        
        if (xml.isStartElement()) {
            // 如果是开始元素,输出标签名
            qDebug() << "Start Element:" << xml.name().toString();

            // 获取属性
            if (xml.name() == "item") {
                QString name = xml.attributes().value("name").toString();
                qDebug() << "Item name:" << name;
            }
        }
        if (xml.isCharacters()) {
            // 如果是字符数据,输出内容
            QString text = xml.text().toString();
            qDebug() << "Text Content:" << text;
        }
    }

    if (xml.hasError()) {
        qDebug() << "Error parsing XML:" << xml.errorString();
    }

    file.close();
}

3. 使用 QXmlStreamWriter 写入 XML

QXmlStreamWriter 也基于事件的流写入器,适用于逐个写入 XML 数据。

3.1. 写入 XML 数据

cpp 复制代码
#include <QXmlStreamWriter>
#include <QFile>
#include <QDebug>

void writeXmlStream() {
    QFile file("output.xml");
    if (!file.open(QIODevice::WriteOnly)) {
        qDebug() << "Failed to open file for writing!";
        return;
    }

    QXmlStreamWriter xml(&file);
    xml.setAutoFormatting(true);  // 设置自动格式化
    xml.writeStartDocument();  // 写入文档开始

    // 写入根元素
    xml.writeStartElement("root");

    // 写入子元素 <item>
    xml.writeStartElement("item");
    xml.writeAttribute("name", "item1");
    xml.writeCharacters("This is item 1");
    xml.writeEndElement();  // 结束 <item> 元素

    xml.writeStartElement("item");
    xml.writeAttribute("name", "item2");
    xml.writeCharacters("This is item 2");
    xml.writeEndElement();  // 结束 <item> 元素

    // 结束根元素
    xml.writeEndElement();

    xml.writeEndDocument();  // 写入文档结束

    file.close();
}

4. 总结

  • QDomDocument 是面向文档的,可以方便地读取、修改和创建 XML 文档。它适用于处理小型文件,并允许你修改整个文档。
  • QXmlStreamReaderQXmlStreamWriter 是基于流的,适用于逐步读取和写入 XML 数据,适合处理大型文件。
  • QDomDocument 使用起来更加简单直观,而 QXmlStreamReader 和 QXmlStreamWriter 则提供了更高效的内存管理,尤其是在处理大型 XML 文件时。
相关推荐
用户805533698035 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner5 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz10 天前
QML Hello World 入门示例
qt
xcyxiner13 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner14 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能16 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G16 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt