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

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.dtcms.com/a/359807.html

相关文章:

  • 基于muduo库的图床云共享存储项目(四)
  • Luma 视频生成 API 对接说明
  • 编写一个用scala写的spark程序从本地读取数据,写到本地
  • 基于Matlab元胞自动机的强场电离过程模拟与ADK模型分析
  • 【Linux】模拟实现Shell(上)
  • 分享一个实用的B站工具箱(支持音视频下载等功能)
  • 【Canvas技法】绘制横向多色旗和竖向多色旗
  • 008.LangChain 输出解析器
  • 备份压缩存储优化方案:提升效率与节省空间的完整指南
  • 新手首次操作SEO核心要点
  • 线程池常见面试问答
  • 【Java实战⑩】Java 集合框架实战:Set与Map的奇妙之旅
  • 基于三维反投影矫正拼接视频
  • 数据结构(04)—— 栈和队列
  • 使用node-red+opencv+mqtt实现相机图像云端查看
  • 零基础入门AutoSar中的ARXML文件
  • Dify 从入门到精通(第 67/100 篇):Dify 的高可用性部署(进阶篇)
  • 从零开始写个deer-flow-mvp-第一天
  • 【C++】类和对象(一)
  • 【全功能图片处理工具详解】基于Streamlit的现代化图像处理解决方案
  • 二.Shell脚本编程
  • 微软开源TTS模型VibeVoice,可生成 90 分钟4人语音
  • 李宏毅NLP-13-Vocoder
  • 中级统计师-统计实务-第四章 专业统计
  • FPGA入门指南:从零开始的可编程逻辑世界探索
  • 【Proteus仿真】点亮小灯系列仿真——小灯闪烁/流水灯/交通灯
  • 常用的20个c++函数
  • 11.1.5 实现文件删除,共享和共享下载排行榜
  • 【GaussDB】排查应用高可用切换出现数据库整体卡顿及报错自治事务无法创建的问题
  • Photoshop - Ps 裁剪并拉直图片