Qt 学习(2)
Qt 学习(2)
Qt 的 QXmlStreamReader
在 Qt 应用程序中访问 XML 格式的文件数据,可以使用 [QXmlStreamReader][sreamreader] 对文件进行读取。关于 QXmlStreamReder 的使用,官方文档中有 QXmlStream Bookmarks Example 的示例可供参考。
常用的方法有:
- TokenType readNext()
读取下一个标记并返回它的类型 - bool readNextStartElement()
在当前元素内,读取到下一个开始元素,若找到开始元素,就返回真,否则返回假 - QXmlStreamAttributes attributes()
返回 StartElement 中的属性 - QString name()
返回标签名,比如读取标签<html>就会返回 html - void skipCurrentElement()
读取到当前元素的结尾,跳过它的子节点 - QString readElementText()
读取元素中间的文本,比如<p>test</p>将会返回 test
对于一个自定义结构的 XML 文件,文件名为 test.xml,如下:
<?xml version="1.0" encoding="UTF-8"?>
<Instructions version="2.0">
<Instruct identifier="#" set="MSP">
<row type="Offset" value="OFFSET_MODE">
<reply type="String" enum="true">
<accept value="AUTO" />
<accept value="MANUAL" />
</reply>
</row>
<row type="Buzzer" value="BUZZER" />
<row type="AC" value="SAG">
<reply type="Double" enum="false" bottom="0" />
</row>
</Instruct>
</Instructions>
首先构造一个 XmlStreamReader,它的构造函数可以接受一个 QIODevice 的指针,一般可以传递一个 QFile 指针,对 xml 文件进行解析:
// void InstructParser::parse(const QString &filename, const QString &set) {
// 打开并读取指令文件
QFile file( filename );
bool opened = file.open( QIODevice::ReadOnly );
if( !opened ) {
qDebug() << "[parse] file not open" ;
return;
}
m_xmlReader = new QXmlStreamReader( &file );
// ![1]
readInstructions();
// ![1]
file.close();
file.deleteLater();
delete m_xmlReader;
// }
构造了 XmlStreamReader 后,通过 readNext() 或者 readNextStartElement() 往下读取节点。
readNext 和 readNextStartElement 方法的使用有些差别,先来看看 readNext 方法:
// void InstructParser::readInstructions()
while( !m_xmlReader->atEnd() ) {
m_xmlReader->readNext();
qDebug() << "[readNext] "<< QString( "%0 %1").arg( m_xmlReader->lineNumber() ).arg( m_xmlReader->tokenString() ) << m_xmlReader->name().toString();
}
输出结果:

可以看到,对于空白行, readNext 函数将会跳过该行,而对于第 3 行 Instruct 起始标签,在它的前面是有一个 tab 缩进的,这里会显示一个类型为 Characters 的元素,然而在第 18 行 </Instructions> 标签前面,其实并没有 tab 缩进,然而这里仍然会显示一个 Characters 元素,并且 17 行的反尖括号后面是没有输入字符的,不知道是不是 Windows 平台下的回车换行符当成一个元素来进行解析的。
接下来是 readNextElement 方法:
// void InstructParser::readInstructions()
while( !m_xmlReader->atEnd() ) {
bool start = m_xmlReader->readNextStartElement();
qDebug() << "[readNextStartElement] "<< start
<< QString( "%0 %1").arg( m_xmlReader->lineNumber() ).arg( m_xmlReader->tokenString() )
<< m_xmlReader->name().toString();
}
输出结果:

可以看到,对于空白行,该方法仍然会忽略掉,但是这个方法不会再出现一些奇怪的 Characters 标签,所有打印出来的元素都是所需要的,当然最后读到文件尾会显示 Invalid 标记。这个方法比 readNext 方法更好用。但是需要注意的是在第 6 行,读取 <accept value="AUTO" /> 时,这里开始标签和结束标签是合并着写的,所以在读到结束标签时,该函数会返回 false,如果 while 循环的判断条件是 m_xmlReader->readNextStartElement(),那么当它遇到结束标签时,将会结束循环。
在读取 XML 文件时,不仅需要针对特定标签做处理,有时还需要注意各个标签之间的层级关系(常见的如 HTML 中 div 标签),如果像前面一样,直接判断 m_xmlReader 是不是到达文件底部,那么就没有办法找出标签之间的层级关系了。
为了找出某个标签中的子标签,就需要在进入标签后,继续用循环进行判断,比如对于上面的 XML 文件:在 InstructParser 中分别有四个方法读取四个标签:
private:
void readInstructions(const QString &set);
void readInstruct(const QString &set, const bool stillRead = false);
void readRow();
void readReply(Instruct *ins);
在 readInstructions 中使用 while 循环对 readInstruct 进行重复调用,在 readInstruct() 中使用 while 循环对 readRow() 进行重新调用……最后其实得到的是一个树状结构,在 readInstruct() 中:
while( m_xmlReader->readNextStartElement() ) {
if( m_xmlReader->name() == "row" ) {
readRow();
}
else
m_xmlReader->skipCurrentElement();
}
在读取之前加上相应的输出语句:
qDebug() << "[reply]" << m_xmlReader->name() << m_attrib.value( "type" ) << m_xmlReader->tokenString();
可以得到以下输出:

这样就得到了所有的节点,有时 m_xmlReader->readNextStartElement() 会跳出循环,可以在 readRow 等函数的结尾加上,以便读取到当前父节点的结束标签:
m_xmlReader->readElementText(); // skip to end tag of reply
Qt 学习(2)的更多相关文章
- QT学习第1天
QT学习第一天 坚持住!! 一 Qt概述 1.Qt发展历史 (1)1991年诞生(Haavard Nord/Eirik Chambe-Eng), (2)1994年创立Troll Tech(奇趣科技) ...
- 【转载】分享一些Qt学习资源,欢迎下载
资源来源:http://bbs.csdn.net/topics/390358737 经过我一翻整理,把一些我收集到的Qt学习资源分享给大家,主要适合新手,老鸟可以直接忽略我.要说明一下,很多资源都是在 ...
- QT学习之路--创建一个对话框
Q_OBJECT:这是一个宏,凡是定义信号槽的类都必须声明这个宏. 函数tr()全名是QObject::tr(),被他处理过的字符串可以使用工具提取出来翻译成其他语言,也就是做国际化使用. 对于QT学 ...
- 转载: Qt 学习之路 2归档
Qt 学习之路 2归档 http://www.devbean.net/2012/08/qt-study-road-2-catelog/
- Qt 学习资料
Qter开源社区http://www.qter.org/ [Qt教程], 作者yafeilinux [视频] QT学习之路:从入门到精通 <C++ Qt 编程视频教程>
- qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果
应大家的要求,还是把完整的project文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm 先看看执行效果,我用的群创7寸屏 ...
- Qt学习博客推荐
附录C Qt资源 C.1 Qt 官方资源 全 球各大公司以及独立开发人员每天都在加入 Qt 的开发社区.他们已经认识到了Qt 的架构本身便可加快应用程序开发进度.这些开发人员,无论是想开发单平台软件. ...
- qt学习教程1.qt开发环境搭建
qt学习教程1.qt开发环境搭建 首先下载qt 下载地址:http://download.qt.io/archive/qt/ 此教程使用的版本为5.1.1 下载好后,打开安装包,然后点下一步 选择一个 ...
- QT学习教程
原地址:http://www.devbean.NET/2012/08/qt-study-road-2-catelog/ 网上看到的不错的教程 本教程以qt5为主,部分地方会涉及qt4.据说非常适合qt ...
- Qt学习之路
Qt学习之路_14(简易音乐播放器) Qt学习之路_13(简易俄罗斯方块) Qt学习之路_12(简易数据管理系统) Qt学习之路_11(简易多文档编辑器) Qt学习之路_10(Qt ...
随机推荐
- 没固定公网 IP 的公司内网实现动态域名解析( 阿里云万网解析 )
情景说明 前段时间应公司需求,需要将内网的服务映射到公网.由于公司使用的是类似家庭宽带的线路,没有固定的公网 IP 地址,所以决定使用域名来完成. 当时有几种方案: 1.花生壳:但是目前需要乱七八糟的 ...
- 利用BIND搭建自己的私有根及授权域
这篇文章是对之前博客写的DNS的再深一层的搭建,其中包括搭建私有根,还有顶级域以及授权子域,转发域,反向解析等等 上一篇DNS的博客链接:http://www.cnblogs.com/hjc4025/ ...
- 51nod - 1179 - 最大的最大公约数 - 枚举
因为 \(\sum\limits_{i=1}^{n}\lfloor\frac{n}{i}\rfloor=O(nlogn)\) 所以直接暴力就可以了. #include<bits/stdc++.h ...
- vue 路由里面的 hash 和 history
对于 Vue 这类渐进式前端开发框架,为了构建 SPA(单页面应用),需要引入前端路由系统,这也就是 Vue-Router 存在的意义.前端路由的核心,就在于 —— 改变视图的同时不会向后端发出请求. ...
- Java框架之Java Bean
链接 知乎https://www.zhihu.com/question/19773379 总结 符合一定规范的编写的Java类,不是一种技术,而是一种规范.大家对于这种规范,总结了很多开发技巧,工具函 ...
- C语言数据结构-栈的实现-初始化、销毁、长度、取栈顶元素、查找、入栈、出栈、显示操作
1.数据结构-栈的实现-C语言 #define MAXSIZE 100 //栈的存储结构 typedef struct { int* base; //栈底指针 int* top; //栈顶指针 int ...
- Kruskal算法 克鲁斯卡尔
30行 #include <iostream> #include <algorithm> using namespace std; int f[5001],n,m,ans=0, ...
- 【三支火把】---# program (n)以及C语言字符对齐的总结
#pragma pack(n) 当n大于结构体中内存占用最大的变量内存时,将按照最大内存变量的字节占用数进行对齐,否则,就根据n进行对齐 情况一: 例一: #pragma pack(4) struct ...
- 项目笔记《DeepLung:Deep 3D Dual Path Nets for Automated Pulmonary Nodule Detection and Classification》(三)(上)结果评估
在(一)中,我将肺结节检测项目总结为三阶段,这里我要讲讲这个项目的第三阶段,至于第二阶段,由于数据增强部分的代码我始终看不大懂,先不讲. 结果评估的程序在evaluationScript文件夹下,这个 ...
- pytorch批训练数据构造
这是对莫凡python的学习笔记. 1.创建数据 import torch import torch.utils.data as Data BATCH_SIZE = 8 x = torch.linsp ...