Qt编程之Xml文件的读取
目录
一、xml的格式说明
二、QT中读取xml的类与常用函数
三、代码思路
四、代码实现
五、结果展示
XML最主要的功能是数据传输,有的时候可以当一个小型的数据库来使用,因为其定义标签高度自由,所以在一些软件需要经常修改的配置变量常常采用xml格式的文件来保存,在需要用到该变量时在事先写好的xml类型文件中进行修改。
本篇博客给出的代码从如何完整读出一个xml文件的思路出发。
逻辑难度不大,但需要读者耐心琢磨。方能写出一个属于自己的读取xml的通用函数。
如果读者对xml格式已经如数家珍,请跳过xml的格式说明,直接进入思路分析
一、xml的格式说明
1.xml的头声明在语法上可有可无,但标准化的书写规范要求一定要有头声明
<?xml version = "1.0" encoding = "utf-8"?>
需要注意的是头声明的前后一定要有问号(?) ,否则在读取xml文件时会无法读取这条语句而造成读取失败。
2.xml有一个根节点,此处我们定义为root,需要强调的是任意节点都可以自定义,其标签定义是高度自由的。
<?xml version = "1.0" encoding = "utf-8"?>
<root><user>章鱼</user><homeland id= "1">中国</homeland><age>18</age>
</root>
根节点下的user和age称作子节点,user相对于homeland来说又是homeland的根节点。所以xml是一个树状结构,什么时候是根什么时候为子都是相对而言,但需要牢记xml文件只有唯一的一个根节点挂着所有的子节点。
二、QT中读取xml的类与常用函数
QT中提供了一个读取xml的类QXmlStreamReader,该类在使用时就是创建一个读取xml文件的迭代器变量。
QXmlStreamReader xmlReader(&filename); //xmlReader就是一个迭代器
常用的一些API函数如下:
1.通过readNextStartElement()挨个读入节点
2.通过isStartElement()和isEndElement()判断是节点的开始和结束
3.通过name()得到当前节点的名字
4.通过readElementText()访问当前节点的内容
5.通过attributes()获取还有属性节点的属性
6.通过atEnd()判断XML文件是否结束
7.通过hasError()判断XML文件是否出错
三、代码思路
在了解xml的格式后,从人的角度出发,我们通常是看根节点,然后看根节点下的节点,读完一整个根节点的内容之后再去看下一个根节点。这样描述有些混乱,读者可以根据上述图1来进行理解。从根节点出发,然后读左一节点,读完左一节点后读中间节点,读完中间节点后读右一节点。
那么转换到机器中(代码)我们需要怎么去做呢?既然是树状结构,且要一段一段的去读,应该只要设置一个迭代器,先找到根节点,然后去寻找根节点下的内容,节点中的内容进行再判定,符合条件执行代码,不符合条件跳过;读完一个节点的内容转到下一个节点去,就是读完左一节点,再到中间节点,直到将根节点遍历结束,也就是将xml文件遍历到文件结尾处。
为此我想到要用if和while循环的结合,在找到某一个节点的条件下,用else if再判定节点中的条件,直到该条件结束之前,都要对该节点下的内容进行响应操作。
代码模式:
if(xmlReader.name() == "根节点名字" && xmlReader.isStartElement())
{xmlReader.readNextStartElement();while(!(xmlReader.name() == "根节点名字" && xmlReader.isEndElement()){ xmlReader.readNextStartElement();if(xmlReader.name() == "节点名字1" && xmlreader.isStartElement()) { while(!(xmlReader.name() == "节点名字1" && xmlReader.isEndElement()){ ...... } } else if(xmlReader.name() == "节点名字2" && xmlreader.isStartElement()){while(!(xmlReader.name() == "节点名字2" && xmlReader.isEndElement()){ ...... } } }
}
四、代码实现
1.准备一个xml文档,名字为testconfig.xml,文档内容如下:
<?xml version ="1.0" encoding ="utf-8"?>
<MSG><Data id ="1"><title><xmlname>kingglore.xml</xmlname><owner>zy</owner><Number>123456</Number><Name>孙悟空</Name><email>孙悟空@qq.com</email><website>孙悟空.hello.cn</website></title></Data><Data id ="2"><Number>7891011</Number><Name>貂蝉</Name><email>貂蝉@qq.com</email><website>貂蝉.hello.cn</website></Data><Data id ="3"><Number>1112131415</Number><Name>小乔</Name><email>小乔@qq.com</email><website>小乔.hello.cn</website></Data><Data id ="4"><Number>1617181920</Number><Name>屠夫</Name><email>屠夫@qq.com</email><website>屠夫.hello.cn</website></Data>
</MSG>
2.创建一个Qt工程,添加一个config类,用来实现xml文件的读取
config.h
#ifndef CONFIG_H
#define CONFIG_H
#include <QXmlStreamReader>
#include <QFile>
#include <QApplication>
#include <QDir>class Config
{
public:Config();
public:QString readConfig(); //读取xml文件的函数
};#endif // CONFIG_H
config.cpp
函数实现中的file.setFileName(qApp->applicationDirPath()+"/Config/testconfig.xml");
Qt开发的程序猿都应该知道,在编译运行后会出现一个新生成的文件夹build-QT_XML-Desktop_Qt_5_12_4_MinGW_32_bit-Debug,小编将程序的保存路径设为D:/QT_code/
其中qApp是头文件QApplication中的指针,指代了该应用程序,在file.setFileName(qApp->applicationDirPath()+"/Config/testconfig.xml");处打断点进入调试
qApp->applicationDirPath()该语句的作用是找到应用程序的路径,获取的是D:/QT_code/build-QT_XML-Desktop_Qt_5_12_4_MinGW_32_bit-Debug
所以还需要在编译后手动在上述路径中手动添加Config文件夹,将testconfig.xml文件放在该文件夹下(也可以自己编写代码实现生成文件夹,读者不妨自己一试)
#include "config.h"
#include <QDebug>Config::Config()
{}QString Config::readConfig()
{QFile file; //需要打开的文件QString nodename; //节点的名字QString OutPut; //最终输出的内容file.setFileName(qApp->applicationDirPath()+"/Config/testconfig.xml"); //查找xml文件的路径if (!file.exists()){qDebug() << "testconfig.xml文件不存在";}else{qDebug() << "testconfig.xml文件存在";}if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) //打开文件{qDebug()<<"打开文件失败!";}else{QXmlStreamReader xmlreader(&file); //读取xml文件的迭代器qDebug() << "testconfig.xml文件存在,且打开文件成功!";while(!xmlreader.atEnd() || !xmlreader.hasError()) //当文件没有结束且没有出错执行下面的代码{xmlreader.readNextStartElement(); //找到非根节点下的第一个子节点nodename = xmlreader.name().toString(); //第一个子节点Dataif(nodename == "Data" && xmlreader.isStartElement()) //如果是第一个子节点的开始执行下列代码{xmlreader.attributes().value("id").toString(); //读取出附加信息OutPut.append(QString("ID:%1").arg(xmlreader.attributes().value("id").toString())); //添加到输出的字符串里OutPut.push_back('\n');while(!(nodename == "Data" && xmlreader.isEndElement())) //如果子节点中的内容没有结束{xmlreader.readNextStartElement();nodename = xmlreader.name().toString();if(nodename == "Number" && xmlreader.isStartElement()){while(!(nodename == "Number" && xmlreader.isEndElement())){OutPut.append(QString("Numeber:%1").arg(xmlreader.readElementText()));OutPut.push_back('\n');}}else if(nodename == "Name" && xmlreader.isStartElement()){while(!(nodename == "Name" && xmlreader.isEndElement())){OutPut.append(QString("Name:%1").arg(xmlreader.readElementText()));OutPut.push_back('\n');}}else if(nodename == "email" && xmlreader.isStartElement()){while(!(nodename == "email" && xmlreader.isEndElement())){OutPut.append(QString("email:%1").arg(xmlreader.readElementText()));OutPut.push_back('\n');}}else if(nodename == "website" && xmlreader.isStartElement()){while(!(nodename == "website" && xmlreader.isEndElement())){OutPut.append(QString("website:%1").arg(xmlreader.readElementText()));OutPut.push_back('\n');OutPut.append("--------------------------------\n");}}}}}file.close();return OutPut;}
}
mainwindow.cpp
此代码里携带的知识点是输出QString类型如何不带双引号
其实很简单,网上多是在说跨平台应用该如何区分'\n'转义字符,有些偏离问题的本意
QString str; str.append("123456"); qDebug()<<qUtf8Printable(str);
如果字符串内存在中文,只需要使用qUtf8Printable(str)将str进行一个转换就行,底层的知识小编不多赘述,这里只讲应用层的东西。
使用ui添加一个控件plainTextEdit来显示读取到的内容。
qDebug()<<qUtf8Printable(str);这条语句是小编在调试程序时方便看输出使用的,如果想要更直观的看到输出信息是否正确,我们还需要在QT_XML.pro文件中找到CONFIG,
添加语句CONFIG += console即可在控制台查看输出结果,更符合VS的调试风格
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "config.h"
#include <QDebug>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);Config config;QString str;str = config.readConfig();qDebug()<<qUtf8Printable(str); //输出不带双引号,需要用qUtf8Printable转换ui->plainTextEdit->appendPlainText("读取XML信息如下:\n");ui->plainTextEdit->appendPlainText(str);
}MainWindow::~MainWindow()
{delete ui;
}
五、结果展示
Qt编程之Xml文件的读取相关推荐
- android include 点击事件,Android编程之include文件的使用方法
本文实例分析了Android编程之include文件的使用方法.分享给大家供大家参考,具体如下: 记得很久以前,听一位大神说,程序员都很懒,不懒惰的程序员不是好程序员,当时不明白什么意思.后来慢慢的懂 ...
- ini文件中文乱码 python_python编程之ini文件处理-configparser模块应用
一.configparser模块是什么 可以用来操作后缀为 .ini 的配置文件: python标准库(就是python自带的意思,无需安装) 二.configparser模块基本使用 2.1 读取 ...
- android中XMl文件的读取
废话不多说了直接上代码: 新建一个Xml文件用于读取: test.xml <Languages cat="1"><lan id="1"> ...
- android的读取xml配置文件,android中XMl文件的读取
废话不多说了直接上代码: 新建一个Xml文件用于读取: test.xml java Eclipse Swift Xcode C# Visual Studio 后台: import android.su ...
- Qt DOM读写XML文件
QXmlStreamReader:一种快速的基于流的方式访问良格式 XML 文档,特别适合于实现一次解析器(所谓"一次解析器",可以理解成我们只需读取文档一次,然后像一个遍历器从头 ...
- Qt:解析xml文件
XML 什么事XML文件 XML,可扩展标记语言(Extensible Markup Language),是一种标记语言.一般用 于数据存储.配置文件存储,(Qt的ui文件就是xml)也可以跨平台跨语 ...
- 从 ADNI 的 XML 文件中读取临床信息
本文配合手把手式介绍 ADNI 影像数据下载使用. 仅给出了如下读取XML文件中的project和subject信息的部分代码,读取其他内容采用一样的写法即可. 只适合自己批量读取一下XML文件,所以 ...
- Qt: QXMLStreamReader,读XML文件实例
主要接口: 1.TokenType QXmlStreamReader::readNext() 功能:读取下一个标记,并返回其类型. 主要的类型有: enum QXmlStreamReader::Tok ...
- C# winform 不同的窗体对同一XML文件进行读取
对数据进行写入 DataTable dingxing = new DataTable(); dingxing.Columns.Add("checker"); dingxing.Co ...
最新文章
- android中一种不支持的lua操作
- R语言ggplot2可视化使用guide_axis函数避免X轴标签互相重叠(Overlapping)、Dodge Overlapping X-axis Text with guide_axis()
- 一款免费好用的代码在线比较工具
- vue-cli项目模板的一些思考
- To B 的产品经理和 To C 的产品经理有什么差别? To B 的产品经理的价值如何体现?
- python installer 在 mac 运行_python – 如何在Mac OS X 10.7中的virtualenv中安装PyAudio
- Tomcat 学习过程4
- yum php mysql5.5_CentOS 5.5使用yum来安装LAMP(php运行环境)
- MATLAB语言初步学习(二)
- 学习_010_Hadoop权威指南
- escplise使用教程_Eclipse使用教程(图文详解)
- 基于51单片机的智能温控风扇
- 如何在php网站上插入站长统计,如何为自己的Wordpress网站添加站长统计代码 | 泰泰博客...
- c语言速算24课程设计,C语言速算24数据结构课程设计.doc
- 2021GKCTF Misc excel骚操作--详解
- 秦储一行拜访陕西省文联和陕西新华出版传媒集团
- oppo手机文件共享媒体服务器,网件:ReadyNAS特色功能之媒体服务器
- 软件评测师考试学习计划
- maven核心,pom.xml详解
- python子列表_关于python:创建子列表