XML读取和设置例子

在Qt C++中,可以使用Qt的 QDomDocument类来读取、更新和保存XML文件。这个类提供了对XML文档的强大操作能力,支持通过DOM(文档对象模型)对XML进行读取、修改、添加和删除节点等操作。
下面是一个详细的例子,演示如何在Qt中使用 QDomDocument来读取、更新一个XML文件,并保存修改后的XML文件。

例子:

假设我们有一个XML文件config.xml,内容如下:

复制代码
<config>
    <database>
        <host>localhost</host>
        <port>3306</port>
        <user>root</user>
        <password>password123</password>
    </database>
    <log>
        <level>info</level>
    </log>
</config>

我们需要做的操作是:

  1. 读取XML文件。
  2. 更新database/port为5432。
  3. 更新log/level为debug。
  4. 保存更新后的XML文件。

代码示例:

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

int main() {
    // 创建一个QFile对象,用于读取XML文件
    QFile file("config.xml");

    // 打开文件以进行读取
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Error opening file for reading";
        return -1;
    }

    // 创建一个QDomDocument对象用于解析XML
    QDomDocument doc;

    // 读取XML内容并加载到QDomDocument中
    if (!doc.setContent(&file)) {
        qDebug() << "Error parsing XML file";
        file.close();
        return -1;
    }
    file.close();  // 关闭文件

    // 获取根元素(在这个例子中是)
    QDomElement root = doc.documentElement();

    // 获取元素
    QDomElement database = root.firstChildElement("database");

    // 获取并更新元素
    QDomElement portElement = database.firstChildElement("port");
    if (!portElement.isNull()) {
        portElement.firstChild().setNodeValue("5432");  // 更新端口号为5432
    }

    // 获取并更新元素中的
    QDomElement logElement = root.firstChildElement("log");
    QDomElement levelElement = logElement.firstChildElement("level");
    if (!levelElement.isNull()) {
        levelElement.firstChild().setNodeValue("debug");  // 更新日志级别为debug
    }

    // 保存修改后的XML文件
    QFile outFile("updated_config.xml");
    if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << "Error opening file for writing";
        return -1;
    }

    QTextStream out(&outFile);
    doc.save(out, 4);  // 使用4个空格的缩进来保存文件
    outFile.close();

    qDebug() << "XML file updated successfully!";
    return 0;
}

代码解释:

1. 读取XML文件
cpp 复制代码
QFile file("config.xml");

if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    qDebug() << "Error opening file for reading";
    return -1;
}
  • 使用QFile打开XML文件并以只读模式读取。
  • 如果文件无法打开,打印错误并退出程序。
2. 加载XML内容
cpp 复制代码
QDomDocument doc;

if (!doc.setContent(&file)) {
    qDebug() << "Error parsing XML file";
    file.close();
    return -1;
}
file.close();
  • 创建一个QDomDocument对象来解析XML文件内容。
  • setContent(&file)将文件内容加载到QDomDocument中。如果解析失败,输出错误并退出。
3. 获取根元素
cpp 复制代码
QDomElement root = doc.documentElement();
  • documentElement()方法返回XML文档的根元素。在本例中,根元素是`config`。
4. 更新XML中的元素
cpp 复制代码
QDomElement database = root.firstChildElement("database");
QDomElement portElement = database.firstChildElement("port");
if (!portElement.isNull()) {
    portElement.firstChild().setNodeValue("5432");
}
  • 使用firstChildElement("database")找到第一个`host`元素。
  • 使用firstChildElement("port")找到`port`元素。
  • 使用firstChild().setNodeValue("5432")更新`port`的值为5432。
    同样地,更新log/level:
cpp 复制代码
QDomElement logElement = root.firstChildElement("log");
QDomElement levelElement = logElement.firstChildElement("level");
if (!levelElement.isNull()) {
    levelElement.firstChild().setNodeValue("debug");
}
  • 使用firstChildElement("log")找到`log`元素。
  • 使用firstChildElement("level")找到`level`元素。
  • 使用firstChild().setNodeValue("debug")更新`level`的值为debug。
5. 保存修改后的XML文件
cpp 复制代码
QFile outFile("updated_config.xml");
if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
    qDebug() << "Error opening file for writing";
    return -1;
}

QTextStream out(&outFile);
doc.save(out, 4);  // 使用4个空格的缩进来保存文件
outFile.close();
  • 创建一个新的QFile对象来保存修改后的XML文件。
  • doc.save(out, 4)将修改后的XML内容写入文件,使用4个空格进行缩进以增强可读性。
  • 保存完成后,关闭文件。
6. 程序输出
cpp 复制代码
qDebug() << "XML file updated successfully!";
  • 如果所有操作都成功完成,输出一条成功消息。

总结:

  • 使用QFile读取XML文件,使用QDomDocument解析和修改XML内容。
  • 通过DOM操作(如firstChildElement()、setNodeValue()等)更新XML中的元素值。
  • 使用doc.save()将修改后的XML文件保存到磁盘。
相关推荐
wowocpp几秒前
rabbitmq 与 Erlang 的版本对照表 win10 安装方法
java·rabbitmq·erlang
deeper_wind4 分钟前
MySQL数据库基础(小白的“升级打怪”成长之路)
linux·数据库·mysql
风象南4 分钟前
SpringBoot基于Java Agent的无侵入式监控实现
java·spring boot·后端
崎岖Qiu10 分钟前
【Spring篇08】:理解自动装配,从spring.factories到.imports剖析
java·spring boot·后端·spring·面试·java-ee
加勒比海涛14 分钟前
Spring Cloud Gateway 实战:从网关搭建到过滤器与跨域解决方案
数据库·redis·缓存
belldeep17 分钟前
java:如何用 JDBC 连接 TDSQL 数据库
java·数据库·jdbc·tdsql
2301_1472583691 小时前
7月2日作业
java·linux·服务器
香饽饽~、1 小时前
【第十一篇】SpringBoot缓存技术
java·开发语言·spring boot·后端·缓存·intellij-idea
小莫分享1 小时前
移除 Java 列表中的所有空值
java
格调UI成品2 小时前
预警系统安全体系构建:数据加密、权限分级与误报过滤方案
大数据·运维·网络·数据库·安全·预警