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

Qt XML 与 JSON 数据处理方法

Qt 提供了强大且易用的 XML 和 JSON 数据处理模块,使开发者能够轻松解析、生成和操作结构化数据。本文将从基础到高级全面解析 Qt 中处理 XML 和 JSON 的方法,包括核心类、使用示例和最佳实践。

一、XML 数据处理

1. Qt XML 模块核心类
类名作用
QXmlStreamReader基于流的 XML 读取器,逐行解析 XML,适合处理大型文件(内存效率高)
QXmlStreamWriter基于流的 XML 写入器,用于生成 XML 文档
QDomDocument基于 DOM(文档对象模型)的 XML 解析器,将整个文档加载到内存中,支持随机访问和修改
QDomElement表示 XML 文档中的元素节点
QDomNode表示 XML 文档中的通用节点(可表示元素、文本、注释等)
2. XML 解析示例:QXmlStreamReader
#include <QCoreApplication>
#include <QFile>
#include <QXmlStreamReader>
#include <QDebug>void parseXML(const QString &fileName) {QFile file(fileName);if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {qDebug() << "无法打开文件:" << fileName;return;}QXmlStreamReader xml(&file);// 遍历 XML 文档while (!xml.atEnd() && !xml.hasError()) {QXmlStreamReader::TokenType token = xml.readNext();// 处理开始元素if (token == QXmlStreamReader::StartElement) {if (xml.name() == "book") {// 获取元素属性QXmlStreamAttributes attributes = xml.attributes();if (attributes.hasAttribute("id")) {QString id = attributes.value("id").toString();qDebug() << "Book ID:" << id;}} else if (xml.name() == "title") {// 获取元素文本QString title = xml.readElementText();qDebug() << "Title:" << title;} else if (xml.name() == "author") {QString author = xml.readElementText();qDebug() << "Author:" << author;}}}if (xml.hasError()) {qDebug() << "XML 解析错误:" << xml.errorString();}file.close();
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);parseXML("books.xml");return a.exec();
}
3. XML 生成示例:QXmlStreamWriter
#include <QCoreApplication>
#include <QFile>
#include <QXmlStreamWriter>void createXML(const QString &fileName) {QFile file(fileName);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {return;}QXmlStreamWriter xml(&file);xml.setAutoFormatting(true);  // 自动格式化(缩进)// 写入 XML 声明xml.writeStartDocument();// 写入根元素xml.writeStartElement("library");// 写入第一个书籍元素xml.writeStartElement("book");xml.writeAttribute("id", "1");xml.writeTextElement("title", "C++ Primer");xml.writeTextElement("author", "Stanley Lippman");xml.writeEndElement();  // 结束 book 元素// 写入第二个书籍元素xml.writeStartElement("book");xml.writeAttribute("id", "2");xml.writeTextElement("title", "Qt 5 C++ GUI Programming Cookbook");xml.writeTextElement("author", "Mark Summerfield");xml.writeEndElement();  // 结束 book 元素// 结束根元素xml.writeEndElement();  // 结束 library 元素// 写入 XML 文档结束xml.writeEndDocument();file.close();
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);createXML("library.xml");return a.exec();
}
4. DOM 方式处理 XML(QDomDocument)
#include <QCoreApplication>
#include <QFile>
#include <QDomDocument>
#include <QDomElement>
#include <QDebug>void modifyXML(const QString &fileName) {QFile file(fileName);if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {return;}QDomDocument doc;QString errorMsg;int errorLine, errorColumn;// 加载 XML 文档if (!doc.setContent(&file, &errorMsg, &errorLine, &errorColumn)) {qDebug() << "XML 加载错误:" << errorMsg << "Line:" << errorLine << "Column:" << errorColumn;file.close();return;}file.close();// 获取根元素QDomElement root = doc.documentElement();// 遍历所有书籍元素QDomNodeList bookList = root.elementsByTagName("book");for (int i = 0; i < bookList.size(); ++i) {QDomElement book = bookList.at(i).toElement();if (!book.isNull()) {// 修改书籍元素的属性if (book.attribute("id") == "1") {book.setAttribute("category", "Programming");}// 添加新元素QDomElement publisher = doc.createElement("publisher");QDomText publisherText = doc.createTextNode("Addison-Wesley");publisher.appendChild(publisherText);book.appendChild(publisher);}}// 保存修改后的 XMLif (file.open(QIODevice::WriteOnly | QIODevice::Text)) {QTextStream stream(&file);doc.save(stream, 4);  // 缩进为4个空格file.close();}
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);modifyXML("library.xml");return a.exec();
}

二、JSON 数据处理

1. Qt JSON 模块核心类
类名作用
QJsonDocument表示完整的 JSON 文档,可从 JSON 文本解析或生成 JSON 文本
QJsonObject表示 JSON 对象(键值对集合),类似 std::map<QString, QJsonValue>
QJsonArray表示 JSON 数组(值的有序列表)
QJsonValue表示 JSON 值(可以是 null、bool、number、string、object 或 array)
QJsonParseError用于存储 JSON 解析过程中的错误信息
2. JSON 解析示例
#include <QCoreApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>void parseJSON(const QString &fileName) {QFile file(fileName);if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {qDebug() << "无法打开文件:" << fileName;return;}// 读取 JSON 数据QByteArray jsonData = file.readAll();file.close();// 解析 JSONQJsonParseError parseError;QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError);if (parseError.error != QJsonParseError::NoError) {qDebug() << "JSON 解析错误:" << parseError.errorString();return;}// 检查是否为 JSON 对象if (jsonDoc.isObject()) {QJsonObject jsonObj = jsonDoc.object();// 获取基本类型值if (jsonObj.contains("name") && jsonObj["name"].isString()) {QString name = jsonObj["name"].toString();qDebug() << "Name:" << name;}// 获取数组if (jsonObj.contains("books") && jsonObj["books"].isArray()) {QJsonArray booksArray = jsonObj["books"].toArray();qDebug() << "Books:";for (int i = 0; i < booksArray.size(); ++i) {if (booksArray[i].isObject()) {QJsonObject bookObj = booksArray[i].toObject();QString title = bookObj["title"].toString();QString author = bookObj["author"].toString();qDebug() << "  Title:" << title;qDebug() << "  Author:" << author;}}}}
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);parseJSON("data.json");return a.exec();
}
3. JSON 生成示例
#include <QCoreApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>void createJSON(const QString &fileName) {// 创建 JSON 对象QJsonObject rootObj;rootObj["name"] = "My Library";rootObj["location"] = "Beijing";rootObj["established"] = 2020;// 创建书籍数组QJsonArray booksArray;// 添加第一本书QJsonObject book1;book1["title"] = "C++ Primer";book1["author"] = "Stanley Lippman";book1["year"] = 2012;book1["available"] = true;booksArray.append(book1);// 添加第二本书QJsonObject book2;book2["title"] = "Qt 5 C++ GUI Programming Cookbook";book2["author"] = "Mark Summerfield";book2["year"] = 2018;book2["available"] = false;booksArray.append(book2);// 将书籍数组添加到根对象rootObj["books"] = booksArray;// 创建 JSON 文档QJsonDocument jsonDoc(rootObj);// 写入文件QFile file(fileName);if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {file.write(jsonDoc.toJson(QJsonDocument::Indented));file.close();}
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);createJSON("library.json");return a.exec();
}

三、XML 与 JSON 的对比与选择

1. 适用场景
特性XMLJSON
数据结构层次结构(元素嵌套)键值对和数组
语法复杂度较高(需要标签闭合、命名空间等)较低(简洁的键值对语法)
可读性较好(标签提供明确语义)好(简洁直观)
解析性能较低(DOM 方式需加载整个文档)较高(轻量级,解析速度快)
数据大小较大(标签增加冗余)较小(紧凑格式)
适用场景配置文件、文档交换(如 RSS、SOAP)网络 API(如 RESTful)、配置文件
2. 转换工具
  • XML → JSON:可通过解析 XML 并手动构建 JSON 对象实现转换。
  • JSON → XML:需创建 XML 结构,将 JSON 键值对映射为 XML 元素或属性。

以下是一个简单的 XML 到 JSON 转换示例:

QJsonValue xmlToJson(const QDomNode &node) {if (node.isElement()) {QDomElement element = node.toElement();QJsonObject obj;// 添加元素属性QDomNamedNodeMap attributes = element.attributes();for (int i = 0; i < attributes.size(); ++i) {QDomNode attribute = attributes.item(i);obj["@" + attribute.nodeName()] = attribute.nodeValue();}// 处理子节点QDomNodeList children = element.childNodes();if (children.size() == 1 && children.at(0).isText()) {// 如果只有文本内容,直接返回文本return QJsonValue(children.at(0).toText().data());} else {// 处理子元素QHash<QString, QJsonArray> childArrays;for (int i = 0; i < children.size(); ++i) {QDomNode child = children.at(i);if (child.isElement()) {QString name = child.nodeName();QJsonValue value = xmlToJson(child);if (childArrays.contains(name)) {childArrays[name].append(value);} else {QJsonArray array;array.append(value);childArrays[name] = array;}}}// 将子元素添加到对象QHashIterator<QString, QJsonArray> it(childArrays);while (it.hasNext()) {it.next();if (it.value().size() == 1) {obj[it.key()] = it.value().at(0);} else {obj[it.key()] = it.value();}}}return QJsonValue(obj);}return QJsonValue();
}

四、最佳实践与注意事项

1. XML 处理建议
  • 大型文件:使用 QXmlStreamReader 逐行解析,避免内存溢出。
  • 复杂操作:若需频繁修改或随机访问,使用 QDomDocument
  • 命名空间:处理含命名空间的 XML 时,使用 QXmlStreamReader::namespaceUri()
  • 错误处理:始终检查解析错误(如 QXmlStreamReader::hasError())。
2. JSON 处理建议
  • 网络数据:优先使用 JSON,因其轻量且易于解析。
  • 严格格式:JSON 格式严格(如键需用双引号),解析前需验证。
  • 空值处理:使用 QJsonValue::isNull()QJsonValue::isUndefined() 区分空值和未定义值。
  • 嵌套结构:处理深层嵌套的 JSON 时,建议先定义数据模型类进行映射。
3. 性能考虑
  • XML:DOM 方式加载整个文档到内存,适合小型文件;流解析适合大型文件。
  • JSON:解析速度通常快于 XML,尤其适合移动端和网络传输。

五、总结

Qt 提供了全面的 XML 和 JSON 处理工具,开发者可根据需求选择合适的方式:

  • XML:适合需要严格结构、丰富元数据和文档交换的场景,提供 DOM 和流两种处理方式。
  • JSON:适合轻量级数据交换、网络 API 和配置文件,语法简洁且解析高效。

掌握这些技术后,可轻松实现数据的存储、传输和交换,为应用开发提供强大的数据处理能力。

http://www.dtcms.com/a/298574.html

相关文章:

  • 文搜图/图搜图
  • OSPF 协议(多区域)
  • Inception网络架构:深度学习视觉模型的里程碑
  • 去甲基化药物联合DLI治疗AML1-ETO阳性
  • 图书推荐-由浅入深的大模型构建《从零构建大模型》
  • 【C++避坑指南】vector迭代器失效的八大场景与解决方案
  • 管理系统模板
  • 应用程序无法正常启动(0xc000007b)怎么办 解决方法详解
  • Matlab学习笔记:结构基础
  • 数仓规范体系的构建
  • SVM多分类实战:从理论到应用的完整指南
  • Linux的磁盘存储管理实操——(下二)——逻辑卷管理LVM的扩容、缩容
  • 5.2.1 javascript 事件对象.内容补充.
  • 从零本地部署使用Qwen3-coder进行编程
  • 1.1.4 建筑隔震减震设计结构要求
  • SpringBoot创建项目的方式
  • Spring AOP `MethodInvocation` 工作原理
  • JavaScript 数组的 every() 和 some() 方法使用
  • Web前端:JavaScript Math内置对象
  • 个人财务记录应用
  • SEC_FirePower 第一天作业
  • 2025年07月25日Github流行趋势
  • 【IDEA】IDEA中如何通过分支/master提交git?
  • haproxy篇
  • 扫描电镜全面解析:工作原理、应用领域与样品制备技巧
  • macbook安装homebrew
  • 为什么数组可以做到时间复杂度为O(1)的随机访问
  • jQuery ID与Class选择器对比
  • C++中的deque
  • js多边形算法:获取多边形中心点,且必定在多边形内部