QT中读取XML文件三种方式 的实例

您所在的位置:网站首页 qt如何加载core文件 QT中读取XML文件三种方式 的实例

QT中读取XML文件三种方式 的实例

2024-07-13 07:56| 来源: 网络整理| 查看: 265

第一部分:QXmlStreamReader

XML(eXtensible Markup Language)是一种通用的文本格式,被广泛运用于数据交换和数据存储(虽然近年来 JSON 盛行,大有取代 XML 的趋势,但是对于一些已有系统和架构,比如 WebService,由于历史原因,仍旧会继续使用 XML)。XML 由 World Wide Web Consortium(W3C)发布,作为 SHML(Standard Generalized Markup Language)的一种轻量级方言。XML 语法类似于 HTML,与后者的主要区别在于 XML 的标签不是固定的,而是可扩展的;其语法也比 HTML 更为严格。遵循 XML 规范的 HTML 则被称为 XHTML(gml(1969)->sgml(1985)->html(1993)->xml(1998))。

我们说过,XML 类似一种元语言,基于 XML 可以定义出很多新语言,比如 SVG(Scalable Vector Graphics)和 MathML(Mathematical Markup Language)。SVG 是一种用于矢量绘图的描述性语言,Qt 专门提供了 QtSVG 对其进行解释;MathML 则是用于描述数学公式的语言,Qt Solutions 里面有一个 QtMmlWidget 模块专门对其进行解释。

另外一面,针对 XML 的通用处理,Qt4 提供了 QtXml 模块;针对 XML 文档的 Schema 验证以及 XPath、XQuery 和 XSLT,Qt4 和 Qt5 则提供了 QtXmlPatterns 模块。Qt 提供了三种读取 XML 文档的方法:

QXmlStreamReader:一种快速的基于流的方式访问良格式 XML 文档,特别适合于实现一次解析器(所谓“一次解析器”,可以理解成我们只需读取文档一次,然后像一个遍历器从头到尾一次性处理 XML 文档,期间不会有反复的情况,也就是不会读完第一个标签,然后读第二个,读完第二个又返回去读第一个,这是不允许的);DOM(Document Object Model):将整个 XML 文档读入内存,构建成一个树结构,允许程序在树结构上向前向后移动导航,这是与另外两种方式最大的区别,也就是允许实现多次解析器(对应于前面所说的一次解析器)。DOM 方式带来的问题是需要一次性将整个 XML 文档读入内存,因此会占用很大内存;SAX(Simple API for XML):提供大量虚函数,以事件的形式处理 XML 文档。这种解析办法主要是由于历史原因提出的,为了解决 DOM 的内存占用提出的(在现代计算机上,这个一般已经不是问题了)。

在 Qt4 中,这三种方式都位于 QtXml 模块中。Qt5 则将QXmlStreamReader/QXmlStreamWriter移动到 QtCore 中,QtXml 则标记为“不再维护”,这已经充分表明了 Qt 的官方意向。

至于生成 XML 文档,Qt 同样提供了三种方式:

QXmlStreamWriter,与QXmlStreamReader相对应;DOM 方式,首先在内存中生成 DOM 树,然后将 DOM 树写入文件。不过,除非我们程序的数据结构中本来就维护着一个 DOM 树,否则,临时生成树再写入肯定比较麻烦;纯手工生成 XML 文档,显然,这是最复杂的一种方式。

使用QXmlStreamReader是 Qt 中最快最方便的读取 XML 的方法。因为QXmlStreamReader使用了递增式的解析器,适合于在整个 XML 文档中查找给定的标签、读入无法放入内存的大文件以及处理 XML 的自定义数据。

每次QXmlStreamReader的readNext()函数调用,解析器都会读取下一个元素,按照下表中展示的类型进行处理。我们通过表中所列的有关函数即可获得相应的数据值:

类型实例有关函数StartDocument documentVersion(),documentEncoding(),isStandaloneDocument()EndDocument  StartElement namespaceUri(),name(),attributes(),namespaceDeclarations()EndElement namespaceUri(),name()Characters text(),isWhitespace(),isCDATA()Comment text()DTD text(),notationDeclarations(),entityDeclarations(),dtdName(),dtdPublicId(),EntityReference name(),text()ProcessingInstruction processingInstructionTarget(),processingInstructionData()

 

 

 

 

 

 

 

 

 

 

 

 

 

 考虑如下 XML 片段:

Einmal ist keinmal

 一次解析过后,我们通过readNext()的遍历可以获得如下信息:

StartDocument StartElement (name() == "doc") StartElement (name() == "quote") Characters (text() == "Einmal ist keinmal") EndElement (name() == "quote") EndElement (name() == "doc") EndDocument

通过readNext()函数的循环调用,我们可以使用isStartElement()、isCharacters()这样的函数检查当前读取的类型,当然也可以直接使用state()函数。

10 34-35 307-308 115 244 9 115 244 9

首先来看头文件:

class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); bool readFile(const QString &fileName); private: void readBookindexElement(); void readEntryElement(QTreeWidgetItem *parent); void readPageElement(QTreeWidgetItem *parent); void skipUnknownElement(); QTreeWidget *treeWidget; QXmlStreamReader reader; private: Ui::MainWindow *ui; };

MainWindow显然就是我们的主窗口,其构造函数也没有什么好说的:

setWindowTitle(tr("XML Reader")); treeWidget = new QTreeWidget(this); QStringList headers; headers


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3