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

Qt中解析XML文件

Qt中解析XML文件

在 Qt 里解析 XML 文件通常有两种主流方式:

  1. DOM(QDomDocument)
    一次性把整个 XML 读进内存,生成一棵 DOM 树,适合体积不大、需要频繁随机访问或修改节点的场景。
  2. SAX(QXmlSimpleReader / QXmlStreamReader)
    按事件流顺序读取,只占用很小内存,适合只读或解析超大 XML 的场景。

下面分别介绍:

一、DOM(QDomDocument)方式

1.首先pro 文件需加模块:

QT += xml

2.book.xml内容如下:

wechat_2025-08-30_231506_144

<bookstore>
<book id="1">
<title>Qt6 C++ GUI Programming</title>
<author>Lee</author>
<year>2022</year>
</book>
<book id="2">
<title>Advanced Qt</title>
<author>Smith</author>
<year>2023</year>
</book>
</bookstore>

具体代码如下:

#include <QCoreApplication>
#include<QFile>
#include<QDomDocument>
#include<QDebug>bool LoadXmlDom(const QString& strFile)
{QFile file(strFile);if(!file.open(QIODevice::ReadOnly)){qWarning() << "Can Not Open File" << strFile;return false;}QDomDocument doc;QString strError;int nErrLine = 0,nErrCol = 0;if(!doc.setContent(&file,&strError,&nErrLine,&nErrCol)){qWarning() << "Prase Error at " << nErrLine <<":"<< nErrCol << ":"<< strError;return false;}file.close();QDomElement root = doc.documentElement();QDomNodeList books = root.elementsByTagName("book");for(int i=0;i<books.size();i++){QDomElement book = books.at(i).toElement();qDebug() << "id = "<< book.attribute("id");qDebug() << "title = "<< book.firstChildElement("title").text();qDebug() << "author = "<< book.firstChildElement("author").text();qDebug() << "year = "<< book.firstChildElement("year").text();}return true;
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// Set up code that uses the Qt event loop here.// Call a.quit() or a.exit() to quit the application.// A not very useful example would be including// #include <QTimer>// near the top of the file and calling// QTimer::singleShot(5000, &a, &QCoreApplication::quit);// which quits the application after 5 seconds.// If you do not need a running Qt event loop, remove the call// to a.exec() or use the Non-Qt Plain C++ Application template.LoadXmlDom(":/XML/res/xml_file/book.xml");return a.exec();
}

代码运行结果:

wechat_2025-08-30_231713_337

小结:

1.QDomDocument:

QDomDocument 类是 Qt 中用于表示整个 XML 文档的核心类。 它作为整个 XML 文档树的入口点和容器,承载了文档的所有内容,包括元素、属性、注释、处理指令等。

QDomDocument 可以将一个符合格式的 XML 字符串或文件解析(“加载”)到内存中,并构建成一棵节点树(DOM 树)。

2.QDomNodeList:

QDomNodeList 类代表一个 QDomNode 对象的列表(集合)。 它本质上是一个只读的、动态的容器,用于存储和访问通过某些 DOM 操作(特别是查询)返回的多个节点。

你可以把它想象成一个临时的快照查询结果集,里面包含了符合特定条件的所有节点。

QDomNodeList 通常不是由你手动创建的,而是通过调用其他 DOM 方法返回的。它的主要作用是提供一种统一的方式来处理和遍历查询到的节点集合。

3.QDomElement:

QDomElement 类是 Qt DOM 模块中用于表示 XML 元素(标签)的核心类。 它继承自 QDomNode,是 DOM 树中最重要的节点类型,用于构建 XML 文档的骨架结构。

你可以把它想象成 XML 文档中的一个个带名字的容器或标签,比如 <book><name><price> 等,它既可以包含文本内容,也可以包含属性,还可以包含其他子元素。

二、SAX(QXmlSimpleReader / QXmlStreamReader)

使用QXmlStreamReader解析XML文件方式如下:

#include <QCoreApplication>
#include<QFile>
#include<QXmlStreamReader>
#include<QDebug>bool LoadXmlStream(const QString& strFile)
{QFile file(strFile);if(!file.open(QIODevice::ReadOnly)){qWarning() << "Can Not Open File" << strFile;return false;}QXmlStreamReader reader(&file);// 用于临时存储当前book的数据QString currentTag;QMap<QString, QString> currentBook;int bookCount = 0;while (!reader.atEnd() && !reader.hasError()) {QXmlStreamReader::TokenType token = reader.readNext();if (token == QXmlStreamReader::StartDocument) {continue; // 跳过文档开始}if (token == QXmlStreamReader::StartElement) {currentTag = reader.name().toString();if (currentTag == "book"){// 开始一本新书,清空临时存储currentBook.clear();// 读取属性QXmlStreamAttributes attributes = reader.attributes();if (attributes.hasAttribute("id")){currentBook["id"] = attributes.value("id").toString();}bookCount++;qDebug() << "\n开始解析第" << bookCount << "本书,ID:" << currentBook["id"];}}if (token == QXmlStreamReader::Characters){// 只有当Characters不在空白处,且上一个StartElement是我们感兴趣的标签时才读取文本if (!reader.isWhitespace() && !currentTag.isEmpty()){QString text = reader.text().toString();// 存储文本到当前book的map中,键为标签名if (currentTag != "bookstore" && currentTag != "book"){currentBook[currentTag] = text;}}}if (token == QXmlStreamReader::EndElement){QString elementName = reader.name().toString();if (elementName == "book"){// 一本书结束,输出或保存这本书的信息qDebug() << "书名:" << currentBook.value("title");qDebug() << "作者:" << currentBook.value("author");qDebug() << "年份:" << currentBook.value("year");qDebug() << "------";}// 遇到结束标签,清空当前标签,防止后面的Characters被误读currentTag.clear();}}if (reader.hasError()){qWarning() << "XML解析错误:" << reader.errorString();}file.close();return 0;
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// Set up code that uses the Qt event loop here.// Call a.quit() or a.exit() to quit the application.// A not very useful example would be including// #include <QTimer>// near the top of the file and calling// QTimer::singleShot(5000, &a, &QCoreApplication::quit);// which quits the application after 5 seconds.// If you do not need a running Qt event loop, remove the call// to a.exec() or use the Non-Qt Plain C++ Application template.qDebug() << "stream流 读取方式";LoadXmlStream(":/XML/res/xml_file/book.xml");return a.exec();
}

代码运行结果:

wechat_2025-08-31_221647_716

小结:

QXmlStreamReader:QXmlStreamReader 类概述

QXmlStreamReader 是 Qt 提供的一个用于读取 XML 文件的快速、高效的流式解析器。它采用"拉模式"(pull parser)解析方式,允许应用程序控制解析过程,按需读取XML内容。

三、两种方式的对比:

总结与选择

特性QXmlStreamReader (流)QDomDocument (DOM)
内存使用,逐次读取,整体加载
性能,尤其对于大文件相对较低,文件越大越明显
访问方式顺序、只读、只向前随机访问,可前后遍历
功能读取读取、修改、创建
易用性需要手动控制流程,稍复杂API直观,易于理解和上手
适用场景大型文件、只读、只需部分数据小型配置文件、需要修改XML、结构简单

选择建议:

  • 绝大多数情况下,优先选择 QXmlStreamReader。特别是处理网络数据、日志文件等大型或未知大小的XML时,它的效率和稳定性更好。
  • 当你需要修改XML结构或内容,或者XML文件很小,并且你希望代码更直观易读时,使用 QDomDocument
  • 对于非常简单的配置读取,有时结合 QSettings(支持XML格式)也可能是更便捷的选择。

适用场景 大型文件、只读、只需部分数据 | 小型配置文件、需要修改XML、结构简单 |

http://www.xdnf.cn/news/19460.html

相关文章:

  • word中插入字符后会自动删除后面的字符
  • Visual Studio Code中launch.json的解析笔记
  • Prometheus之启用--web.enable-remote-write-receiver
  • 对于一个多层感知机,参数初始化的时候不是已经把权重的范围根据方差进行优化过了,为什么还要进行正则化惩罚过大权重
  • springboot整合minio实现上传下载搭建minio
  • Unity转抖音小游戏重点摘记
  • 学生请假就餐系统
  • 计算机网络---http(超文本传输协议)
  • XPlayer播放器APP:安卓平台上的全能视频播放器
  • LeetCode每日一题,2025-8-31
  • TFS-2002《Analysis and Efficient Implementation of a Linguistic Fuzzy C-Means》
  • 【量化回测】backtracker整体架构和使用示例
  • Rsync 数据同步工具及实时同步配置
  • SAP PP中的MRP
  • 【OpenGL】LearnOpenGL学习笔记18 - Uniform缓冲对象UBO
  • 模型系列(篇三)-Llama
  • vscode克隆远程代码步骤
  • 合约服务架构-OOP 方式
  • leetcode 371 两个整数之和
  • 微软开源TTS模型VibeVoice,可生成 90 分钟4人语音
  • TFS-1996《The Possibilistic C-Means Algorithm: Insights and Recommendations》
  • 一些八股总结
  • 如何快速学习新技能
  • Redis 7.0 高性能缓存架构设计与优化
  • [Android] UI进阶笔记:从 Toolbar 到可折叠标题栏的完整实战
  • IDEA插件ApifoxHelper
  • C++ 登录状态机项目知识笔记
  • Nginx虚拟主机配置
  • CTFshow系列——命令执行web69-72
  • 数据结构 04(线性:双向链表)