Qt之XML

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 简述XML(EXtensible Markup Language - 可扩展标记语言)是一种用于记录多种数据类型的标记语言。使用 XML 可以将各类型的文档定义为容易读取的格式,便于用户读取。而且,在应用程序中使用 XML,可以轻松实现数据交换。简述使用 XML 模块XML 的访问方式DOMSAXSAX2 介绍XML 流QXmlSt

简述

XML(EXtensible Markup Language - 可扩展标记语言)是一种用于记录多种数据类型的标记语言。使用 XML 可以将各类型的文档定义为容易读取的格式,便于用户读取。而且,在应用程序中使用 XML,可以轻松实现数据交换。

使用 XML 模块

要链接到 XML 模块,需要在 qmake 项目文件 .pro 中添加:

QT += xml

包含模块中类的定义,使用:

#include <QtXml>

XML 的访问方式

Qt 提供了两种访问 XML 文档的方式:DOM 和 SAX。

  • DOM 方式:将 XML 文档转换为树形结构存储到内存中,再进行读取,消耗的内存比较多。此外,由于文档都已经存储到内存,所以需要频繁实现修改等操作时,使用起来比较方便。

  • SAX 方式:相比于 DOM,SAX 是一种速度更快,更有效的方法,它逐行扫描文档,一边扫描一边解析(由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势)。而且相比于 DOM,SAX 可以在解析文档的任意时刻停止解析。但操作复杂,很难修改 XML 数据。

DOM

DOM Level 2 是用于 XML 接口的一个 W3C 推荐标准,将 XML 文档的组成映射为一个树结构。DOM Level 2 的规范可以在 http://www.w3.org/DOM/ 上找到。

DOM 提供了一个访问和更改 XML 文件内容和结构的接口。它创建了一个文档的分层视图(树视图),因此,与 SAX2 接口相反,在解析之后,文档的对象模型常驻在内存中,这使得操作变得更加容易。
文档树中的所有 DOM 节点都是 QDomNode 的子类,文档本身由 QDomDocument 对象表示。

Qt 为 DOM 提供了用于操作 XML 的多种 C++类,均以 QDom 开头:

描述
QDomAttr 表示一个 QDomElement 的属性
QDomCDATASection 表示一个 XML CDATA 部分
QDomCharacterData 表示 DOM 中的一个通用字符串
QDomComment 表示一个 XML 注释
QDomDocument 表示一个 XML 文档
QDomDocumentFragment QDomNodes 树,通常不是一个完整的 QDomDocument
QDomDocumentType 表示文档树中的 DTD
QDomElement 表示 DOM 树中的一个元素
QDomEntity 代表一个 XML 实体
QDomEntityReference 代表一个 XML 实体引用
QDomImplementation DOM 实现的功能的信息
QDomNamedNodeMap 包含一个节点集合,节点可以通过名字来访问
QDomNode 一个 DOM 树中所有节点的基类
QDomNodeList QDomNode 对象列表
QDomNotation 代表一个 XML 表示法
QDomProcessingInstruction 代表 XML 处理指令
QDomText 表示解析的 XML 文档中的文本数据

QDom 类通常使用如下:

QDomDocument doc("mydocument");
QFile file("mydocument.xml");
if (!file.open(QIODevice::ReadOnly))
    return;
if (!doc.setContent(&file)) {
    file.close();
    return;
}
file.close();

// 打印出作为最外层元素的所有直接子元素的元素名称
QDomElement docElem = doc.documentElement();

QDomNode n = docElem.firstChild();
while(!n.isNull()) {
    QDomElement e = n.toElement(); // 尝试将节点转换为元素
    if(!e.isNull()) {
        cout << qPrintable(e.tagName()) << endl; // 节点真的是一个元素
    }
    n = n.nextSibling();
}

// 这里,我们在文档的末尾添加一个新元素
QDomElement elem = doc.createElement("img");
elem.setAttribute("src", "myimage.png");
docElem.appendChild(elem);

一旦 doc 和 elem 超出范围,代表 XML 文档的整个内部树被删除。

要使用 DOM 创建文档,请使用如下代码:

QDomDocument doc("MyML");
QDomElement root = doc.createElement("MyML");
doc.appendChild(root);

QDomElement tag = doc.createElement("Greeting");
root.appendChild(tag);

QDomText t = doc.createTextNode("Hello World");
tag.appendChild(t);

QString xml = doc.toString();

有关文档对象模型的更多信息,请参阅文档对象模型(DOM)Level 1evel 2 Core 核心规范。

SAX

SAX 是用于 XML 解析器的基于事件的标准接口。XML 类的设计遵循 SAX2 Java interface,名称适合 Qt 的命名约定。对于任何使用 SAX2 的人来说,使用 Qt XML 类应该非常容易。

SAX2 介绍

SAX2 接口是一种事件驱动的机制,能够为用户提供文档信息。这里提到的“事件”意味着解析器报告的东西。例如,它遇到了一个开始标记,或者结束标记等。

为了使它不那么抽象,考虑以下示例:

<quote>A quotation</quote>

在读取(SAX2 解析器通常被称为“读取器”)时,上述文档将触发三个事件:

  • 出现开始标记(<quote>)。
  • 找到字符数据(即文本)“A quotation”。
  • 解析结束标记(</ quote>)。

每次发生这样的事件时,解析器就会报告它,可以设置事件处理程序来响应这些事件。

虽然这是一种快速、简单地读取 XML 文档的方法,但是操作困难,因为数据不存储,而是串行处理并丢弃。DOM 接口读取并以树结构存储整个文档,这需要更多的内存,但更容易操作文档的结构。

Qt XML 模块提供了一个抽象类 QXmlReader,它定义了潜在的 SAX2 读取器的接口,它有一个简单的 XML 读取器的实现 - QXmlSimpleReader(目前只有这一个,在将来的版本中,可能有更多的具有不同属性的读取器。例如:验证解析器),通过子类化,很容易适应。

读取器通过特殊的 handler 类来报告解析事件:

Handler 类 描述
QXmlContentHandler 报告与文档内容相关的事件(例如:开始标签或字符)
QXmlDTDHandler 报告与 DTD 相关的事件(例如:符号声明)
QXmlErrorHandler 报告解析期间发生的错误或警告(QXmlParseException 用于向使用 QXmlErrorHandler 的接口报告错误)
QXmlEntityResolver 在解析期间报告外部实体,并允许用户解析外部实体本身,而不是将其留给读取器。
QXmlDeclHandler 报告进一步的 DTD 相关事件(例如:属性声明)
QXmlLexicalHandler 报告与文档的词法结构相关的事件(DTD 的开头、注释等)

由于处理程序类只描述接口,因此必须实现所有函数。Qt 提供了 QXmlDefaultHandler 类使之变得更容易:它实现所有函数的默认行为(不做任何操作),所以可以子类化它,只需要实现感兴趣的函数即可。

要读取输入的 XML 数据,需要使用特殊类 QXmlInputSource(QXmlReader 子类的输入数据)。

除了已经提到的,以下 SAX2 支持类还提供了其他有用的功能:

描述
QXmlAttributes 用于向来是元素事件中传递属性
QXmlLocator 用于获取事件的实际解析位置
QXmlNamespaceSupport 用于为读取器实现命名空间支持。注意:命名空间不会更改解析行为,它们只通过处理程序进行报告。

XML 流

从 4.3 版本开始,Qt 提供了两个新的类来读写 XML:QXmlStreamReader 和 QXmlStreamWriter。

流读取器将 XML 文档报告为标记流。这与 SAX 不同,因为 SAX 应用程序提供处理程序从解析器接收 XML 事件,而 QXmlStreamReader 驱动循环,在需要时从读取器中提取标记。这种拉取方法使得构建递归下降解析器成为可能,允许 XML 解析代码被拆分成不同的方法或类。

QXmlStreamReader 是一个格式良好的 XML 1.0 解析器,排除外部解析实体。因此,只要没有错误发生,应用程序代码就可以确保由 QXmlStreamReader 提供的数据满足 W3C 对于格式良好的 XML 的标准。否则,可以使用诸如 atEnd()、error() 和 hasError() 的函数来检查和查看错误。

QXmlStreamReader

应用程序中,QXmlStreamReader 类比用于 SAX 解析的 QXmlSimpleReader 类速度更快,且更好用。QXmlStreamReader 类用于读取数据,他可以通过 QIODevice 和 QByteArray 读取列数据。

一个典型的 QXmlStreamReader 循环:

QXmlStreamReader xml;
...
while (!xml.atEnd()) {
    xml.readNext();
    ... // 做处理
}
if (xml.hasError()) {
    ... // 做错误处理
}

QXmlStreamWriter

QXmlStreamWriter 类仅通过数据流写入 XML 数据,该类由成员函数 setDevice() 指定的 QIODevice 运行。

下面的简化代码片段,显示了该类用缩进编写格式化 XML 的基本用法:

QXmlStreamWriter stream(&output);
stream.setAutoFormatting(true);
stream.writeStartDocument();
...
stream.writeStartElement("bookmark");
stream.writeAttribute("href", "http://qt-project.org/");
stream.writeTextElement("title", "Qt Project");
stream.writeEndElement(); // bookmark
...
stream.writeEndDocument();

使用哪种方式

虽然 Qt XML 模块提供了 XML 对 SAX 和 DOM 标准的 C++ 实现,但是助手中有这么一句话:

The module is not actively maintained anymore. Please use the QXmlStreamReader and QXmlStreamWriter classes in Qt Core instead.

此模块不再进行积极地维护,请使用Qt Core 中的 QXmlStreamReader 和 QXmlStreamWriter 类代替。

也就是说,助手更建议我们使用 QXmlStreamReader 和 QXmlStreamWriter 类,而非 XML 模块。

更多参考

目录
相关文章
|
XML 数据格式
|
XML JavaScript API
Qt通过Doc模式读取XML并设计一个增删改查方便的操作类
Qt通过Doc模式读取XML并设计一个增删改查方便的操作类
230 0
|
XML JavaScript 数据格式
QT Dom方式操作XML
本文提供了读者已知的XML文件语法结构,对xml基础知识不作介绍,仅介绍了QT操作xml的方法之一。
303 0
|
XML 数据格式
QT5.2 QDomDocument操作xml
QT5.2 QDomDocument操作xml
233 0
QT5.2 QDomDocument操作xml
|
XML 数据格式
Qt 利用XML文档,写一个程序集合 四
接上一个 启动外部程序 https://blog.csdn.net/z609932088/article/details/80775086
103 0
|
XML 数据格式
Qt 利用XML文档,写一个程序集合 三
接上一篇 https://blog.csdn.net/z609932088/article/details/80774950
118 0
|
XML 数据格式
Qt 利用XML文档,写一个程序集合 二
接上一篇文章 https://blog.csdn.net/z609932088/article/details/80774663 XML文件的读写
230 0
Qt 利用XML文档,写一个程序集合 二
|
XML 数据格式
Qt 利用XML文档,写一个程序集合 一
接到领导需求安排,说公司未来的硬件设备会越来越多,与每个设备对应的设备检测和设置程序也会增多。导致软甲太多,不好掌控。所以希望做一个完整的软件,但是呢,每个子程序还得独立,应为每个用户购买的设备不是一样的。
125 0
Qt 利用XML文档,写一个程序集合 一
|
XML 编解码 JSON
Qt-QML-C++交互实现文件IO系统-后继-读取XML文件和创建XML文件
在前面两篇中,大致完成了一个文件IO的读和写操作。前面两篇文章链接
338 0
Qt-QML-C++交互实现文件IO系统-后继-读取XML文件和创建XML文件
|
XML 存储 JavaScript
QT开发(四十一)——XML文件解析基础
  一、XML文档简介   XML(Extensible Markup Language,可扩展标记语言),是一种通用的文本格式,被广泛运用于数据交换和数据存储,而不是显示数据。XML的标签没有被预定义,用户需要在使用时自行进行定义。XML是W3C(万维网联盟)的推荐标准。相对于数据库表格的二维表示,XML使用的树形结构更能表现出数据的包含关系,作为一种文本文件格式,XML简单明了的特性使得它在信息存储和描述领域非常流行。
623 0

相关课程

更多