Qt怎么解析XML QXmlStreamReader和QDomDocument

12次阅读

qt推荐QxmlstreamReader用于大文件和高性能场景,QdomDocument适合小文件且需随机访问;前者流式解析内存友好,后者构建DOM树便于查询修改。

Qt怎么解析XML QXmlStreamReader和QDomDocument

Qt 提供两种主流 XML 解析方式:基于事件流的 QXmlStreamReader(推荐用于大文件、高性能场景)和基于 DOM 树的 QDomDocument(适合小文件、需随机访问节点的场景)。选哪个取决于你的数据规模和使用需求。

用 QXmlStreamReader 流式解析(轻量、高效、内存友好)

QXmlStreamReader 是 Qt 推荐的现代 XML 解析方式,它逐标记读取,不一次性加载整个文档,内存占用低,适合处理几百 KB 到几十 MB 的 XML 文件。你需要手动推进读取位置,并根据 Token 类型(StartElementCharactersEndElement 等)编写状态逻辑。

关键步骤:

  • 构造 QXmlStreamReader,传入 QIODevice*(如 QFileQByteArray
  • 循环调用 readNext()readNextStartElement()
  • isStartElement()name()Attributes()readElementText() 等方法提取内容
  • 注意错误检查:hasError() + errorString()

示例片段(读取 Lippman):

reader.readNextStartElement(); // 跳到
if (reader.name() == “book”) {
  QString title = reader.attributes().value(“title”).toString();
  reader.readNextStartElement(); // 到
  if (reader.name() == “author”) {
    QString author = reader.readElementText(); // 自动跳过结束标签
  }
}

用 QDomDocument 构建完整 DOM 树(直观、易查、适合小文件)

QDomDocument 将整个 XML 加载进内存并构建树形结构,支持 XPath 风格查找(elementsByTagName)、遍历子节点(firstChildElement)、修改节点等操作。适合配置文件ui 描述等体积较小(一般建议 ≤ 1MB)、需要反复查询或编辑的场景。

常用操作:

  • 调用 setContent() 加载 XML 字符串或文件(返回 bool 表示是否成功)
  • documentElement() 获取根节点
  • firstChildElement("xxx")elementsByTagName("xxx") 查找元素
  • attribute("name")text()childnodes() 获取属性/文本/子节点

示例片段:

QDomDocument doc;
if (doc.setContent(file, &error)) {
  QDomElement root = doc.documentElement();
  QDomNodeList books = root.elementsByTagName(“book”);
  for (int i = 0; i     QDomElement book = books.at(i).toElement();
    QString title = book.attribute(“title”);
    QString author = book.firstChildElement(“author”).text();
  }
}

怎么选?看这三点

文件大小:> 2MB 建议用 QXmlStreamReader;≤ 500KB 可放心用 QDomDocument
访问模式:只需顺序读一遍 → 流式;要多次查不同节点、增删改 → DOM。
可维护性:DOM 代码更直白,适合快速开发;流式逻辑稍复杂但性能可控、不易 OOM。

补充提醒

两者都不支持 DTD 和 XSD 验证(Qt 不内置 XML Schema 支持),如需校验,得自己预处理或换用第三方库(如 libxml2)。
若 XML 来自网络或不可信源,务必检查编码(如 UTF-8 bom)、实体引用(&)、嵌套深度,避免解析异常。
Qt6 中 QDomDocument 仍可用,但官方文档更倾向推荐 QXmlStreamReader 作为默认方案。

text=ZqhQzanResources