当前位置: 首页 > news >正文

Qt C++ :XML文件处理工具 <QXml>模块

文章目录

  • QXml 模块概览
  • QDOM(Document Object Model)
    • 创建与加载 XML 文档
    • 遍历与查询节点
    • 创建与修改节点
    • 删除节点
    • 保存 XML 到文件
    • 使用示例
  • QXmlStreamReader 高效 XML 读取器
  • QXmlStreamWriter 结构化 XML 写入器


Qt 提供了一套完善的 XML 处理工具,统称为 QXml 模块。它包含多种解析器和操作方式,适用于不同场景下的 XML 读写需求。

QXml 模块概览

Qt 的 XML 处理能力主要通过以下几类技术实现:

类/模块类型特点适用场景
QXmlStreamReader流式读取低内存、高效、只进大文件解析、配置读取
QXmlStreamWriter流式写入高效、结构化输出生成 XML 文件
QDomDocument / QDomElementDOM 模型随机访问、可修改小型 XML、频繁修改
QXmlQuery / QXmlSchemaXPath/XSLT/Schema复杂查询与验证高级 XML 处理
  • QXmlStreamReaderQXmlStreamWriter 是现代 Qt 开发的首选,性能高、内存友好。
  • QDom 适合小型、需要频繁修改的 XML 文档。

QDOM(Document Object Model)

QDom 模块提供了对 XML 文档的 DOM(Document Object Model)解析支持,适用于需要随机访问、修改和构建 XML 文档的场景。

QDom 模块主要由以下几个核心类构成:

  • QDomDocument: 表示整个 XML 文档,是所有其他节点的根容器。
  • QDomElement: 表示 XML 元素(标签),可以包含属性和子节点。
  • QDomNode: 所有节点类型的基类(如元素、文本、注释等)。
  • QDomNodeList: 存储一组 QDomNode 对象的列表,常用于存储查询结果。
  • QDomAttr: 表示元素的属性。
  • QDomText: 表示元素内的文本内容。
  • QDomProcessingInstruction: 表示处理指令(如 <?xml version="1.0"?>)。

创建与加载 XML 文档

创建空文档并添加根元素

#include <QDomDocument>
#include <QFile>
#include <QTextStream>QDomDocument doc("mydocument");
QDomElement root = doc.createElement("root");
doc.appendChild(root);

从文件加载 XML

QFile file("config.xml");
if (!file.open(QIODevice::ReadOnly)) {qWarning() << "Cannot open file";return;
}QDomDocument doc("mydoc");
if (!doc.setContent(&file)) {qWarning() << "Failed to parse XML";file.close();return;
}
file.close();// 获取根元素
QDomElement root = doc.documentElement();

从字符串加载 XML

QString xmlString = "<data><item>Value</item></data>";
QDomDocument doc;
doc.setContent(xmlString);

遍历与查询节点

获取根元素

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

遍历子节点

QDomNode node = root.firstChild();
while (!node.isNull()) {if (node.isElement()) {QDomElement element = node.toElement();qDebug() << "Element:" << element.tagName();}node = node.nextSibling();
}

根据标签名查找元素

QDomNodeList elements = root.elementsByTagName("item");
for (int i = 0; i < elements.count(); ++i) {QDomElement item = elements.at(i).toElement();qDebug() << "Item value:" << item.text();
}QString text = element.text(); // QDomElement 的便捷方法,比 firstChild().nodeValue() 更安全

使用 firstChildElement() 快速定位

QDomElement child = root.firstChildElement("child"); // 获取第一个名为 "child" 的子元素
QDomElement grandChild = child.firstChildElement("grandChild");

创建与修改节点

创建新元素并添加属性

QDomElement newElement = doc.createElement("user");
newElement.setAttribute("id", "123");
newElement.setAttribute("name", "Alice");

添加文本内容

QDomText textNode = doc.createTextNode("Hello World");
newElement.appendChild(textNode);

将新元素添加到父节点

root.appendChild(newElement);

修改现有元素内容

QDomElement firstItem = root.firstChildElement("item");
firstItem.setTagName("updatedItem"); // 修改标签名
firstItem.setAttribute("status", "processed");
firstItem.firstChild().setNodeValue("New Value"); // 修改文本内容

删除节点

QDomElement elementToRemove = root.firstChildElement("obsolete");
if (!elementToRemove.isNull()) {root.removeChild(elementToRemove);
}

保存 XML 到文件

QFile outFile("output.xml");
if (outFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {QTextStream stream(&outFile);doc.save(stream, 4); // 4 表示缩进空格数outFile.close();
}

使用示例

<?xml version="1.0" encoding="UTF-8"?>
<configuration><appSettings><appName>MyAwesomeApp</appName><version>1.0.0</version><debugMode>true</debugMode><logLevel>INFO</logLevel></appSettings><userPreferences><theme>Dark</theme><language>en_US</language><autoSaveInterval>300</autoSaveInterval></userPreferences>
</configuration>
// modify_xml.cpp
#include <QDomDocument>
#include <QFile>
#include <QTextStream>
#include <QDebug>bool modifyConfig() {QFile file("config.xml");// 步骤1:读取文件if (!file.open(QIODevice::ReadOnly)) {qDebug() << "❌ 无法打开文件:" << file.fileName();return false;}QDomDocument doc;if (!doc.setContent(&file)) {file.close();qDebug() << "❌ 无法解析XML内容";return false;}file.close();// 步骤2:获取根元素QDomElement root = doc.documentElement();if (root.tagName() != "configuration") {qDebug() << "❌ 无效的根元素:" << root.tagName();return false;}// 步骤3:定位并修改节点(仅修改,不添加/删除)// 修改应用名称QDomElement appNameElem = root.firstChildElement("appSettings").firstChildElement("appName");if (!appNameElem.isNull()) {appNameElem.firstChild().setNodeValue("UpdatedApp");qDebug() << "✅ 已修改 appName 为:UpdatedApp";}// 修改版本号QDomElement versionElem = root.firstChildElement("appSettings").firstChildElement("version");if (!versionElem.isNull()) {versionElem.firstChild().setNodeValue("2.1.0");qDebug() << "✅ 已修改 version 为:2.1.0";}// 修改调试模式QDomElement debugElem = root.firstChildElement("appSettings").firstChildElement("debugMode");if (!debugElem.isNull()) {debugElem.firstChild().setNodeValue("false");qDebug() << "✅ 已修改 debugMode 为:false";}// 修改主题QDomElement themeElem = root.firstChildElement("userPreferences").firstChildElement("theme");if (!themeElem.isNull()) {themeElem.firstChild().setNodeValue("Light");qDebug() << "✅ 已修改 theme 为:Light";}// 修改语言QDomElement langElem = root.firstChildElement("userPreferences").firstChildElement("language");if (!langElem.isNull()) {langElem.firstChild().setNodeValue("zh_CN");qDebug() << "✅ 已修改 language 为:zh_CN";}// 步骤4:保存修改回文件if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {qDebug() << "❌ 无法写入文件:" << file.fileName();return false;}QTextStream stream(&file);stream.setCodec("UTF-8");  // 确保编码正确doc.save(stream, 4);       // 4个空格缩进,格式清晰file.close();qDebug() << "✅ 所有修改已成功保存到 config.xml";return true;
}

QXmlStreamReader 高效 XML 读取器

QXmlStreamReader 采用“拉式解析”(pull parsing)模型,逐个读取 XML 事件(如开始标签、文本、结束标签),内存占用极小。

#include <QXmlStreamReader>
#include <QFile>QFile file("data.xml");
if (!file.open(QIODevice::ReadOnly)) {qWarning() << "Cannot open file";return;
}QXmlStreamReader reader(&file);while (!reader.atEnd()) {QXmlStreamReader::TokenType token = reader.readNext();if (token == QXmlStreamReader::StartDocument) {qDebug() << "Start document:" << reader.documentVersion();}if (token == QXmlStreamReader::StartElement) {if (reader.name() == "book") {// 读取属性QString id = reader.attributes().value("id").toString();qDebug() << "Found book with ID:" << id;}}if (token == QXmlStreamReader::Characters && !reader.isWhitespace()) {qDebug() << "Text:" << reader.text().toString();}if (token == QXmlStreamReader::EndElement) {if (reader.name() == "book") {qDebug() << "End of book element";}}
}if (reader.hasError()) {qWarning() << "XML Error:" << reader.errorString();
}file.close();

常用方法:

  • readNext():读取下一个 XML 事件。
  • name():获取当前元素或属性的名称。
  • attributes():返回当前元素的属性集合(QXmlStreamAttributes)。
  • text():获取文本内容。
  • skipCurrentElement():跳过当前元素及其所有子元素(处理未知或复杂嵌套时非常有用)。

QXmlStreamWriter 结构化 XML 写入器

QXmlStreamWriter 提供了简单、安全的方式来生成格式良好的 XML 文件。

#include <QXmlStreamWriter>
#include <QFile>QFile file("output.xml");
if (!file.open(QIODevice::WriteOnly)) {return;
}QXmlStreamWriter writer(&file);
writer.setAutoFormatting(true); // 自动格式化(缩进)writer.writeStartDocument(); // <?xml version="1.0" encoding="UTF-8"?>
writer.writeStartElement("library");writer.writeStartElement("book");
writer.writeAttribute("id", "1");
writer.writeTextElement("title", "C++ Primer");
writer.writeTextElement("author", "Stanley Lippman");
writer.writeEndElement(); // </book>writer.writeEndElement(); // </library>
writer.writeEndDocument(); // 结束文档file.close();

常用方法:

  • writeStartDocument() / writeEndDocument():文档开始与结束。
  • writeStartElement() / writeEndElement():元素开始与结束。
  • writeAttribute():写入属性。
  • writeTextElement():快速写入带文本的元素。
  • writeComment():写入注释。
  • setAutoFormatting(bool):启用自动缩进和换行。
http://www.dtcms.com/a/461005.html

相关文章:

  • 门诊场景评测深度分析报告:医生-病人-测量代理交互对诊断影响机制研究(上)
  • 海康威视 2DC 系列球机手机直连实用教程
  • MyBatis Mapper XML 核心详解
  • 加强局网站建设网站建设域名多少钱
  • 记录最新 Neo4j 安装过程(截图实操)、使用、踩坑 Neo4j 5.26.13、JDK 17安装
  • JavaWeb项目部署到Tomcat的三种方法
  • MyBatis配置全解析:核心要点详解
  • apache-tomcat 安装部署
  • 如何为卫生中心构建安全高效的网络系统?
  • 抖音代运营业务介绍seo文案范例
  • 珠海网站排名提升昆明网站建设frf
  • 使用 Loki + Promtail + Grafana 实现 Docker 容器日志采集与可视化
  • Dockerfile实战案例详解
  • Paimon系列:主键表流读之changelog producer
  • 本地 Docker 镜像送上云:腾讯云无服务器与容器化全栈迁移实战
  • win10安装spark3.1详细流程(小白用)
  • Spark on k8s部署
  • Kotlin 内联函数、高阶函数、扩展函数
  • 用化学方法nmp溶剂从佳能cmos传感器上剥离拜耳矩阵和微透镜
  • Apache Tomcat 详解
  • 矩阵奇异值分解(SVD)中Golub–Kahan 双对角化 + 对双对角矩阵的隐式QR详解
  • QT MVC中Model的特点及使用注意事项
  • wordpress最快仿站宁波网络营销服务
  • 徕卡RTC360助力铝单板设计效率提升
  • EasyExcel 读取 Excel 文件指南
  • LabVIEW光栅旋转式光谱仪
  • 上海营销网站设计去设计公司还是去企业
  • 怎么查询自己注册的商标东营网站建设课程定位优化
  • 【rabbitmq 高级特性】RabbitMQ 延迟队列全面解析
  • linux学习笔记(22)线程同步——线程信号量