一、流方法解析XML简介

QT 4.3开始,QT引入了两个新的类来读取和写入XML文档:QXmlStreamReader和QXmlStreamWriter。

QXmlStreamReader类提供了一个快速的解析器通过一个简单的流API来读取良构的XML文档,是作为QT的SAX解析器的替代者出现的,比SAX解析器更快更方便。 QXmlStreamReader可以从QIODevice或QByteArray中读取数据。QXmlStreamReader以一种快速的基于流的方式访问良格式XML文档,特别适合于实现一次解析器(所谓“一次解析器”,即只需读取文档一次,然后像一个遍历器从头到尾一次性处理XML文档,期间不会有反复的情况,只能顺序访问标签)。

QXmlStreamReader使用了递增式的解析器,适合于在整个XML文档中查找给定的标签、读入无法放入内存的大文件以及处理XML的自定义数据。每次QXmlStreamReader的readNext()函数调用,解析器都会读取下一个标记,按照返回的标记类型进行处理。

QXmlStreamWriter类提供了简单流接口的XML写入器,写入XML文档只需要调用相应的标记写入函数来写入相关数据。

二、QXmlStreamReader

1、QXmlStreamReader简介

QXmlStreamReader提供了一个通过流接口读取良构XML文档的快速解析器。QXmlStreamReader比QT自身的SAX解析器更快、更方便。在某些情况下,作为在应用程序中使用QXmlStreamReader解析器比使用DOM树要更快、更方便。QXmlStreamReader可以从QIODevice或者QByteArray中读取数据。

与SAX解析器相似,流读取器的基本原理是将XML文档报告为一个标记(tokens)流。QXmlStreamReader与SAX主要的不同在于这些XML标记如何被报告。对于SAX来说,应用程序必须提供处理器来从解析器获得XML事件;对于QXmlStreamReader来说,应用程序代码自身驱动循环,在需要的时候从读取器中一个一个地拉出标记。这是通过调用readNext()函数完成的。readNext()函数中,读取器从输入流中读取下一个标记,然后返回标记类型。isStartElement()和text()等函数用来检查这个标记获取我们已经读取的标记的信息。这种拉取标记方式的最大好处就是可以构建递归继承解析器,这意味着可以很容易将你的XML解析代码分成不同的函数方法或类。

QXmlStreamReader经典的循环如下:

QXmlStreamReader xml;

...

while (!xml.atEnd()) {

xml.readNext();

... // do processing

}

if (xml.hasError()) {

... // do error handling

}

QXmlStreamReader使用了递增式的解析器,适合于在整个XML文档中查找给定的标签、读入无法放入内存的大文件以及处理XML的自定义数据。每次QXmlStreamReader的readNext()函数调用,解析器都会读取下一个标记,按照返回的元素类型进行处理。

QXmlStreamReader是不包括外部实体的良构XML 1.0解析器。只要没有错误发生,应用程序代码就能确保流读取器提供的数据满足W3C的良构XML文档标准。例如,你能肯定所有标签真正地被嵌套和恰当关闭,引用到使用正确替换文本替换的内部实体中,并且属性已经被规范化或是根据内部DTD子集增加。

当解析时,如果错误发生,atEnd()和hasError() 会返回true, error()函数返回发生的错误。errorString()、lineNumber()、columnNumber()和characterOffset() 函数会构造适当的错误或警告信息。为了简化应用程序代码,QXmlStreamReader包含发送错误信号的机制,发送错误机制可以发送由相同的错误处理函数处理的自定义错误。

QXmlStream理解和解析命名空间,namespaceUri()函数返回元素所在的命名空间,name()函数返回元素的本地名字。命名空间和名字的结合唯一标识了一个元素。

QXmlStreamReader是一个递增解析器,能够处理由于文档分块到达而不能够立即解析文档全部内容的情况。在整个我能当被解析完成前,当读取器超出了文档数据范围时,读取器会报告一个PrematureEndOfDocumentError错误。当更多的数据到达时,无论是调用了addData()函数还是网络设备有了更多可用的数据,读取器将从PrematureEndOfDocumentError错误中恢复,继续解析readNext()的新数据。

例如,如果你的应用程序从网络中读取数据,你会发一个网络请求到管理者并接收返回的网络应答。由于QNetworkReply是一个IO设备,你要连接QNetworkReply的readyRead() 信号到自定义的槽函数。在槽函数中,你可以使用readAll读取所有的可用数据,使用addData()函数传递数据到XML流读取器。到时调用自定义的从读取器中读取XML事件的解析函数。

由于不存储整个文档树在内存中,QXmlStreamReader设计的比较节省内存。

2、QXmlStreamReader成员函数

void QXmlStreamReader::addData(const QByteArray &data)

void QXmlStreamReader::addData(const QString &data)

void QXmlStreamReader::addData(const char *data)

给读取器增加更多的数据读取,如果读取器没有设备,什么也不做

bool QXmlStreamReader::atEnd() const

如果读取器读取到了XML文档结束或是发生错误导致读取中止时,返回true

QXmlStreamAttributes QXmlStreamReader::attributes() const

返回开始元素的属性

void QXmlStreamReader::clear()

从读取器中删除任何设备或数据,重置内部状态为初始状态

QIODevice *QXmlStreamReader::device() const

返回和读取器关联的当前设备,没有则返回0

Error QXmlStreamReader::error() const

返回当前错误的类型

bool QXmlStreamReader::hasError() const

如果有错误发生,返回true

TokenType QXmlStreamReader::readNext()

读取下一个标记,返回它的类型

void QXmlStreamReader::setDevice(QIODevice *device)

设置读取器的当前设备到device

TokenType QXmlStreamReader::tokenType() const

返回当前标记的类型

QStringRef QXmlStreamReader::documentEncoding() const

如果标记类型是StartDocument,返回XML声明中指定的编码字符串

QStringRef QXmlStreamReader::documentVersion() const

如果标记类型是StartDocument,返回XML声明中指定的版本字符串

QStringRef QXmlStreamReader::name() const

返回一个StartElement、EndElement或是EntityReference的本地名字

bool QXmlStreamReader::isWhitespace() const

如果读取器报告字符串只由空格组成,返回true

bool QXmlStreamReader::isStartElement() const

如果标记类型是StartElement,返回true

bool QXmlStreamReader::isStartDocument() const

如果标记类型是StartDocument,返回true

bool QXmlStreamReader::isEndDocument() const

如果标记类型是EndDocument,返回true

bool QXmlStreamReader::isEndElement() const

如果标记类型是EndElement,返回true

3、QXmlStreamReader实例

#include #include #include #include #include  int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); QFile file("test.xml"); if (!file.open(QFile::ReadOnly | QFile::Text)) { qDebug()<"; if (reader.attributes().hasAttribute("id")) qDebug() << reader.attributes().value("id"); } if (type == QXmlStreamReader::EndElement) qDebug() << "" << reader.name() << ">"; if (type == QXmlStreamReader::Characters && !reader.isWhitespace()) qDebug() << reader.text(); }  // 如果读取过程中出现错误,那么输出错误信息 if (reader.hasError()) { qDebug() << "error: " << reader.errorString(); } file.close();  return a.exec();}

三、QXmlStreamWriter

1、QXmlStreamWriter简介

QXmlStreamWriter类提供了简单流接口的XML写入器。

QXmlStreamWriter操作由setDevice()函数指定的IO设备,API函数简单而直接:对于要写入的每个XML标记或事件,写入器都提供了具体的函数。

2、QXmlStreamWriter成员函数

bool QXmlStreamWriter::autoFormatting() const

如果自动格式化功能打开,返回true

QTextCodec *QXmlStreamWriter::codec() const

返回当前赋值给流的编码方式

QIODevice *QXmlStreamWriter::device() const

返回关联QXmlStreamWriter的当前设备,如果没有,返回0

bool QXmlStreamWriter::hasError() const

如果流写入到底层设备失败,返回true

void QXmlStreamWriter::setAutoFormatting(bool enable)

如果enable为true,打开自动格式化功能

void QXmlStreamWriter::setCodec(QTextCodec *codec)

设置流的编码为codec

void QXmlStreamWriter::setCodec(const char *codecName)

设置流的编码为codeName的编码

void QXmlStreamWriter::setDevice(QIODevice *device)

设置当前设备到device,如果流要写入到QByteArray,可以创建一个QBuffer设备

void QXmlStreamWriter::writeAttribute(const QString &namespaceUri, const QString &name, const QString &value)

写入名为name,值为vlaue的属性到命名空间namespaceUri

void QXmlStreamWriter::writeAttribute(const QString &qualifiedName, const QString &value)

写入一个名为qualifiedName,值为value的属性

void QXmlStreamWriter::writeAttribute(const QXmlStreamAttribute &attribute)

写入一个属性attribute

void QXmlStreamWriter::writeAttributes(const QXmlStreamAttributes &attributes)

写入属性向量attributes

void QXmlStreamWriter::writeTextElement(const QString &namespaceUri, const QString &name, const QString &text)

写入一个名为name的文本元素到namespaceUri命名空间,内容为text

void QXmlStreamWriter::writeTextElement(const QString &qualifiedName, const QString &text)

写入一个名为qualifiedName,文本为text的文本元素

void QXmlStreamWriter::writeStartElement(const QString &namespaceUri, const QString &name)

写入一个命名空间为namespaceUri,名为name的开始元素

void QXmlStreamWriter::writeStartElement(const QString &qualifiedName)

写入qualifiedName的开始元素

void QXmlStreamWriter::writeStartDocument(const QString &version)

void QXmlStreamWriter::writeStartDocument()

void QXmlStreamWriter::writeStartDocument(const QString &version, bool standalone)

void QXmlStreamWriter::writeProcessingInstruction(const QString &target, const QString &data = QString())

写入一个target和data的处理指令

void QXmlStreamWriter::writeEndElement()

关闭前一个开始元素

void QXmlStreamWriter::writeEndDocument()

关闭所有打开的开始元素,换行

void QXmlStreamWriter::writeCharacters(const QString &text)

写入文本

3、QXmlStreamWriter实例

QXmlStreamWriter的使用只需要调用相应的标记写入函数来写入相关数据。

#include #include #include #include #include  int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); QFile file("test.xml"); if (!file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate)) { qDebug() << "Error: cannot open file"; return 1; } QXmlStreamWriter stream(&file); stream.setAutoFormatting(true); //写入StartDocument stream.writeStartDocument();//写入StartElement stream.writeStartElement("bookmark"); //写入标签属性 stream.writeAttribute("href

解析xml_QT开发(四十四)——流方法解析XML相关推荐

  1. 即时通讯音视频开发(十四):实时音视频数据传输协议介绍

    概述 随着移动互联网的快速发展以及智能终端性能的逐步提高,智能终端间进行实时音视频通讯成为移动互联网发展的一个重要方向.那么如何保证智能终端之间实时音视频数据通讯成为一个很现实的问题. 实际上,实时音 ...

  2. 【Visual C++】游戏开发笔记四十四 浅墨DirectX教程十二 网格模型和X文件使用面面观

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8586540 作者:毛星云(浅墨 ...

  3. 【Visual C++】游戏开发笔记四十四 浅墨DirectX教程十二 网格模型和X文件使用面面观...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhmxy555/article/details/8586540 作者:毛星云(浅墨) ...

  4. 自学Web开发第十四天-基于VB和ASP.NET;丰富数据呈现:TreeView控件的使用及与GridView控件联动,深入研究从GridView中取数据

    自学Web开发第十四天-基于VB和ASP.NET:丰富数据呈现:TreeView控件的使用及与GridView控件联动,深入研究从GridView中取数据 GridView操作数据库后,刷新TreeV ...

  5. Python编程基础:第四十四节 方法重写Method Overriding

    第四十四节 方法重写Method Overriding 前言 实践 前言 我们前面说了,子类继承于父类,可以调用父类的所有属性和方法.那么如果我们想在继承的过程中重新书写父类的某些方法,此时就用到了方 ...

  6. 【正点原子Linux连载】第四十四章 设备树下的LED驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  7. 【正点原子FPGA连载】第四十四章MT9V034摄像头HDMI显示实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...

  8. [系统安全] 四十四.APT系列(9)Metasploit技术之基础用法万字详解及防御机理

    您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列.因此,我重新开设了这个专栏,准备系统整理和深入学习系统安全.逆向分 ...

  9. 如何选择适合你的兴趣爱好(四十四),武当

    围城网的摇摇今天给大家带来了"如何选择适合你的兴趣爱好"系列专辑的第四十四讲--武当.武当功夫由张三丰祖师始创,集百家之长,融道家养身为一体,以阐功夫真理,扬长道教文化为宗旨.武当 ...

最新文章

  1. 追查连接mysql的客户端
  2. 具备这四点品质的建站系统就爱了吧!
  3. oracle 裸设备 ocr,裸设备建立RAC的OCR设备不一致的问题
  4. 云炬Android开发报错处理教程 完美解决Android Studio maven { url ‘https://jitpack.io‘ } 无法下载问题
  5. 【python数据挖掘课程】二十一.朴素贝叶斯分类器详解及中文文本舆情分析
  6. 前端开发--面试题整理(JS篇)
  7. 花书+吴恩达深度学习(二五)直面配分函数(CD, SML, SM, RM, NCE)
  8. 程序员如何从初中级历练为高级开发者?
  9. 降价上标(Github风味)?
  10. Unity3D基础16:网格过滤器和渲染器
  11. 5. Adapter Pattern(适配器模式)
  12. hr面试性格测试30题_HR经典面试30题
  13. MSP430 G2553 Launchpad实现电容测量
  14. (专升本)信息安全(应用安全策略、网络安全策略)
  15. Codeforces 949A Zebras(构造)
  16. 一般熟练盲打需要多久_如何学会盲打, 大概需要多长时间?
  17. 杰理之BQB 的 profile 测试【篇】
  18. 3D变电站园区3D可视化电力监控管理平台
  19. JAVA的使用idea导包
  20. Delta Lake 学习笔记(一)

热门文章

  1. Integer类的装箱和拆箱到底是怎样实现的?
  2. ubuntu的两种网络连接模式
  3. DataTable筛选某列最大值
  4. C#读书笔记之继承、接口与抽象类续
  5. 怎么使用Nginx服务开启HTTPS
  6. [jQuery基础] jQuery核心函数和工具方法
  7. Node.js「一」—— Node.js 简介 / Node.js 模块 / 包 与 NPM
  8. php 语义解析,[扩展推荐] PHP 语义化版本(SemVer)辅助库
  9. 江诗丹顿geneve系列_南京江诗丹顿维修保养多少钱石英手表清洗
  10. 计算机复试上机辅导班,软件工程考研辅导班:考研院校2020年计算机/软件工程复试经验总结...