39.Qt XML
1.使用QXmlStreamReader读取XML,可以读取内存中容纳不了的特大文件,或者读取在XML文档中定制的文档的内容。
xml文件(in1.xml)
<?xml version="1.0"?>
<bookindex>
<entry term="sidebearings">
<page></page>
<page>-</page>
<page>-</page>
</entry>
<entry term="subtraction">
<entry term="of pictures">
<page></page>
<page></page>
</entry>
<entry term="of vectors">
<page></page>
</entry>
</entry>
</bookindex>
main.cpp
#include <QtGui> #include <iostream>
#include "xmlstreamreader.h" int main(int argc, char *argv[])
{
//创建QApplication对象
QApplication app(argc, argv);
QDir::setCurrent(app.applicationDirPath());//设置路径为当前目录 //创建两个标签
QStringList labels;
labels << QObject::tr("Terms") << QObject::tr("Pages"); //树形控件窗口
QTreeWidget treeWidget;
//设置第一行
treeWidget.setHeaderLabels(labels);
//设置可以伸缩
treeWidget.header()->setResizeMode(QHeaderView::Stretch);
//设置窗口标题
treeWidget.setWindowTitle(QObject::tr("XML Stream Reader"));
//树形控件显示
treeWidget.show(); //创建对象,对xml读取
XmlStreamReader reader(&treeWidget); reader.readFile("in1.xml"); return app.exec();
}
xmlstreamreader.h
#ifndef XMLSTREAMREADER_H
#define XMLSTREAMREADER_H #include <QXmlStreamReader> class QTreeWidget;
class QTreeWidgetItem; class XmlStreamReader
{
public:
XmlStreamReader(QTreeWidget *tree); bool readFile(const QString &fileName); private:
//解析一个含有0或0个以上<entry>元素的<bookindex>...</bookindex>
void readBookindexElement();
//解析一个含有0个或0个以上<entry>元素的<entry>...</entry>元素
//以及嵌套任意层次的含有0或0个以上<entry>元素
void readEntryElement(QTreeWidgetItem *parent);
//解析一个<page>...</page>元素
void readPageElement(QTreeWidgetItem *parent);
//跳过不能识别的元素
void skipUnknownElement(); //保存传进来的treeWidget
QTreeWidget *treeWidget;
//读取对象
QXmlStreamReader reader;
}; #endif
xmlstreamreader.cpp
#include <QtGui>
#include <QtXml>
#include <iostream> #include "xmlstreamreader.h" XmlStreamReader::XmlStreamReader(QTreeWidget *tree)
{
//初始化指针
treeWidget = tree;
} bool XmlStreamReader::readFile(const QString &fileName)
{
//尝试打开文件
QFile file(fileName);
//只读,文本方式打开。如果出错,返回出错信息。
if (!file.open(QFile::ReadOnly | QFile::Text)) {
std::cerr << "Error: Cannot read file " << qPrintable(fileName)
<< ": " << qPrintable(file.errorString())
<< std::endl;
return false;
} //如果成功,则将这个file设置为输入设备,用于读数据
reader.setDevice(&file); //从流中读取一个数据
reader.readNext();
//如果没到文件末尾
while (!reader.atEnd()) {
//如果是开始标签
if (reader.isStartElement()) {
if (reader.name() == "bookindex") {
//解析bookindex
readBookindexElement();
}
else
{
//否则给出出错信息
reader.raiseError(QObject::tr("Not a bookindex file"));
}
}
else
{
//继续读下一个标签
reader.readNext();
}
} file.close();
//如果处理出现错误就会返回
//是否存在解析错误?
if (reader.hasError()) {
std::cerr << "Error: Failed to parse file "
<< qPrintable(fileName) << ": "
<< qPrintable(reader.errorString()) << std::endl;
return false;
}
//是否存在文件错误?
else if (file.error() != QFile::NoError)
{
std::cerr << "Error: Cannot read file " << qPrintable(fileName)
<< ": " << qPrintable(file.errorString())
<< std::endl;
return false;
}
return true;
} void XmlStreamReader::readBookindexElement()
{
//读下一个标签
reader.readNext();
while (!reader.atEnd()) {
//如果到结束标签,则结束while循环
if (reader.isEndElement()) {
reader.readNext();
break;
} //如果是开始标签
if (reader.isStartElement())
{
if (reader.name() == "entry")
{
//调用处理entry的函数
readEntryElement(treeWidget->invisibleRootItem());
}
else
{
//调用未知的处理函数
skipUnknownElement();
}
}
else
{
//如果不是开始标签则读取下一个
reader.readNext();
}
}
} //每当遇到<entry>开始标签,就调用readEntryElement()函数
void XmlStreamReader::readEntryElement(QTreeWidgetItem *parent)
{
//遇到一个<entry>就在树形控件中增加一个条目
QTreeWidgetItem *item = new QTreeWidgetItem(parent);
//设置第0个,为对应的term项所表示的值
item->setText(, reader.attributes().value("term").toString()); //读下一个
reader.readNext();
while (!reader.atEnd()) {
//如果遇到关闭标签,跳出循环
if (reader.isEndElement()) {
reader.readNext();
break;
} //如果遇到的是开始标签
if (reader.isStartElement()) {
//如果是<entry>标签
if (reader.name() == "entry") {
//递归调用
readEntryElement(item);
}
//如果是<page>标签
else if (reader.name() == "page")
{
readPageElement(item);
}
//未知标签
else
{
skipUnknownElement();
}
}
else
{
reader.readNext();
}
}
} //读取页面信息
void XmlStreamReader::readPageElement(QTreeWidgetItem *parent)
{
//读标签内容,调用reader.readElementText,reader会停留在结束标签位置上,需要跳过
QString page = reader.readElementText();
//如果是结束标识,则跳到下一个进行读取
if (reader.isEndElement())
reader.readNext(); //第一个文本
QString allPages = parent->text();
//如果不为空加上,
if (!allPages.isEmpty())
allPages += ", ";
//加上标签内容
allPages += page;
//设置
parent->setText(, allPages);
} //如果遇到未知标签也读取,直到跳过该标签的关闭标签
void XmlStreamReader::skipUnknownElement()
{
//遇到未知的继续读取下一个标签
reader.readNext();
//继续读下一个,如果没到末尾
while (!reader.atEnd()) {
if (reader.isEndElement()) {
reader.readNext();
break;
} //如果是开始,继续递归,直到遇到第一个未知的关闭标签
if (reader.isStartElement()) {
skipUnknownElement();
} else {
reader.readNext();
}
}
}
39.Qt XML的更多相关文章
- Qt XML的使用
Qt中对于XML文件的写入有两种方式,一个是使用QXmlStreamWriter,另一个则为使用Dom.stream流的形式相对来说更加灵活,而且适合处理大文件.Dom方式由于是将内容加载到了内存中进 ...
- Qt XML读取写入操作
XML(eXtensible Markup Language,可扩展标记语言)是普通用于数据交换和数据存储的一种多用途文本文件格式: SVG(可标量矢量图形)XML格式,QtSvg模块提供了可用于载入 ...
- QT XML文档的解析 QXmlStreamReader, DOM,SAX 三种解析方法 简单示例
0. xml文档如下 <?xml version="1.0"?> <bookindex> <entry term="sidebearings ...
- Qt Xml Dom
//Dom方式更改节点信息 bool XmlTools::SetValue(QString name,float exposure,float gain,float gamma,int brightn ...
- Qt中三种解析xml的方式
在下面的随笔中,我会根据xml的结构,给出Qt中解析这个xml的三种方式的代码.虽然,这个代码时通过调用Qt的函数实现的,但是,很多开源的C++解析xml的库,甚至很多其他语言解析xml的库,都和下面 ...
- Qt中使用DOM解析XML文件或者字符串二(实例)
介绍 在Qt中提供了QtXml模块实现了对XML数据的处理,我们在Qt帮助中输入关键字QtXml Module,可以看到该模块的类表.在这里我们可以看到所有相关的类,它们主要是服务于两种操作XML文档 ...
- Qt中使用DOM解析XML文件或者字符串(实例)
因为需要读取配置文件,我的配置文件采用xml:因此编写了使用qt读取xml文件内容的代码,xml文件如下: <?xml version="1.0" encoding=&quo ...
- QXmlStreamReader/QXmlStreamWriter实现Qt下xml文件读写
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QXmlStreamReader/QXmlStreamWriter实现Qt下xml文件读写 ...
- Qt 学习之路 2(60):使用 DOM 处理 XML
Qt 学习之路 2(60):使用 DOM 处理 XML 豆子 2013年8月3日 Qt 学习之路 2 9条评论 DOM 是由 W3C 提出的一种处理 XML 文档的标准接口.Qt 实现了 DO ...
随机推荐
- 从Android源码分析View绘制
在开发过程中,我们常常会来自定义View.它是用户交互组件的基本组成部分,负责展示图像和处理事件,通常被当做自定义组件的基类继承.那么今天就通过源码来仔细分析一下View是如何被创建以及在绘制过程中发 ...
- 【Oracle】利用trace文件重建控制文件
重建步骤: 1.生成trace文件: alter database backup controlfile to trace; 2.找到生成的trace文件: show parameter dump u ...
- Mac使用ssh登录远程linux系统查看jetty日志及同时使用github工具
转载请注明出处:http://www.houxiurong.com/?post=27 Mac默认是安装了ssh工具软件的. 先用mac的 终端工具生成 id_rsa 和id_rsa.pub 秘钥,生成 ...
- iphone通讯录的备份与恢复
最近在做iOS系统通讯录备份到服务器,并且可以从服务器中下载备份文件恢复到手机的功能,部分实现细节记录如下. 将iphone系统通讯录生成.vcf文件 ABAddressBookRef address ...
- (转)shiro权限框架详解05-shiro授权
http://blog.csdn.net/facekbook/article/details/54910606 本文介绍 授权流程 授权方式 授权测试 自定义授权realm 授权流程 开始构造Secu ...
- 【seo】title / robots / description / canonical
1.title title,就是浏览器上显示的那些内容,不仅用户能看到,也能被搜索引擎检索到(搜索引擎在抓取网页时,最先读取的就是网页标题,所以title是否正确设置极其重要. 1)title一般不超 ...
- 任务调度开源框架Quartz概述
任务调度开源框架Quartz 几乎每个项目中都用到了自动任务处理功能.所以在任务调度的功能很常用,但是一个好的任务调度程序是一个颇具挑战性的工作.最近用到Quartz这个框架,感觉很好,所以进行学习. ...
- Python笔记16-------类
1.类的定义 (1)#括号中要加入父类,如果没有则默认为object,万类之源 class 类名(父类): '类的文档字符串' 类体代码 若类什么都不做,则类只作为命名空间,仅作为一个容器. (2)类 ...
- python之子类调用父类的两种方式
第一种方式 直接在子类中调用父类名: Vehicle.__init__(self,name,speed,load,power)#调用父类的实例 Vehicle.run(self) #调用父类的方法 # ...
- Bonjour/Zeroconf with Arduino
转自:http://gkaindl.com/software/arduino-ethernet/bonjour Bonjour/Zeroconf with Arduino DownloadVersio ...