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 ...
随机推荐
- 适配器模式(adapter)C++实现
意图:将一个类的接口转换成客户希望的另一个接口. 适用性:1.你想使用一个已存在的类,而它的接口不符合你的需求. 2.你想创建一个可以复用的类,该类可以与其它不相关的类或不可预见的类协同工作. 类适配 ...
- Jquery中的bind()方法的一点问题
bind()方法绑定事件的时候,第二个参数是函数,如果代码都写在函数里面,没有任何问题.但是,直接调用外部封装的函数需要注意,出错的例子: <!doctype html> <html ...
- SPOJ DISQUERY LCA + 倍增
裸题,如此之水- Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn ...
- AM335X用RGB888连接LCD如何以16位色彩模式显示图片
在AM335x中,在连接显示屏的时候,存在一个问题.这个在am335x Sillicon Errata已经提到过 在RGB888模式中 而对于RGB565模式的硬件连接 不难看出,这个RGB是反的 ...
- Tarjan算法 (强联通分量 割点 割边)
变量解释: low 指当前节点在同一强连通分量(或环)能回溯到的dfn最小的节点 dfn 指当前节点是第几个被搜到的节点(时间戳) sta 栈 vis 是否在栈中 ans 指强连通分量的数量 top ...
- MAVEN 构建包的引用
1.什么叫构建包的引用? 当你存在两个maven项目分别是项目A,项目B时,且项目B要引用项目A的方法,那么你就用把项目A打成*.jar架包,放到本地的Maven仓库提供给项目B去引用. A.用命令到 ...
- python第七周:反射、异常
1.反射: 1.1定义:通过字符串映射或修改程序运行时的状态.属性.方法 1.2有以下四个方法: (1)hasattr(object,str) 判断object对象中是否有对应的方法或属性,返回值:T ...
- NOIP2018提高组金牌训练营——动态规划专题
NOIP2018提高组金牌训练营——动态规划专题 https://www.51nod.com/Live/LiveDescription.html#!#liveId=19 多重背包 二进制优化转化成01 ...
- Ubuntu14.04 Anaconda
我虚拟机Ubuntu14.04上的Python已经存在了两个版本,一个是python 2.7,一个是Python 3.4.想在它上面安装Anaconda,但又有所顾虑.我先想到的是,先卸载Ubuntu ...
- tomcat 内存溢出问题(OutOfMemoryError: PermGen space)
导入公司项目的时候出现的问题,在此记录处理方法. tomcat在启动的时候报错:OutOfMemoryError: PermGen space PermGen space的全称是Permanent G ...