基本介绍
1 老版的Qt提供了两种访问XML文件的方式:DOM和SAX。
2 DOM 方式:将 XML 文档转换为树形结构存储到内存中,再进行读取,消耗的内存比较多。此外,由于文档都已经存储到内存,所以需要频繁实现修改等操作时,使用起来比较方便。
3 SAX 方式:相比于 DOM,SAX 是一种速度更快,更有效的方法,它逐行扫描文档,一边扫描一边解析(由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势)。而且相比于 DOM,SAX 可以在解析文档的任意时刻停止解析。但操作复杂,很难修改 XML 数据。
自QT4.3版本开始,QT提供了两个新类来读写XML:QXmlStreamReader 和 QXmlStreamWriter。读写方式可类比于SAX。目前QT已经停止对DOM和SAX的维护与更新。
4 QXmlStreamWriter 类提供了一个使用简单的流 API,用于写入 XML,与之相对应的是 QXmlStreamReader(读取 XML)。
5 QXmlStreamReader类支持对XML读取的操作。对于 XML 的内容,通常情况下,我们只关心 XML 元素的解析。这时,可以通过 QXmlStreamReader 中的便利函数 readNextStartElement() 来实现。
实例
1案例介绍:读取qt运行当前目录下所有文件,通过类QXmlStreamWriter将其按照xml格式对文件进行写操作,并将xml文件保存在当前目录。通过类QXmlStreamReader读取生成的xml文件,并输出。(注意需要.pro文件中添加 xml 如 QT += xml)
生成的XML文件内容为:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<文件列表>
<目录 Dirname="E:/myTest/myXml/build-myXml-Desktop_Qt_5_9_1_MinGW_32bit-Debug">
<文件名>.qmake.stash</文件名>
<文件名>debug</文件名>
<文件名>fileList.xml</文件名>
<文件名>Makefile</文件名>
<文件名>Makefile.Debug</文件名>
<文件名>Makefile.Release</文件名>
<文件名>release</文件名>
<文件名>ui_widget.h</文件名>
</目录>
</文件列表>
对XML文件不了解,可先阅读:了解XML文档,一篇足以
读取到xml内容为:
"E:/myTest/myXml/build-myXml-Desktop_Qt_5_9_1_MinGW_32bit-Debug"
"文件名:.qmake.stash"
"文件名:debug"
"文件名:fileList.xml"
"文件名:Makefile"
"文件名:Makefile.Debug"
"文件名:Makefile.Release"
"文件名:release"
"文件名:ui_widget.h"
头文件代码:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QDir>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void readFile();
void writeFile();
private:
Ui::Widget *ui;
QDir *dir;
};
#endif // WIDGET_H
cpp文件代码
#include "widget.h"
#include "ui_widget.h"
#include <QFileInfoList>
#include <QDebug>
#include <QXmlStreamAttributes>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
dir = new QDir(".");
writeFile();
readFile();
}
void Widget::writeFile(){
QFileInfoList infoList = dir->entryInfoList();
infoList.removeFirst();
infoList.removeFirst();
QString strFile("fileList.xml");
QFile file(strFile);
if (!file.open(QFile::WriteOnly | QFile::Text)) { // 只写模式打开文件
qDebug() << QString("Cannot write file %1(%2).").arg(strFile).arg(file.errorString());
return;
}
QXmlStreamWriter writer(&file);
writer.setCodec("UTF-8"); // XML 编码
writer.setAutoFormatting(true); // 自动格式化
writer.writeStartDocument("1.0", true); // 开始文档(XML 声明)
writer.writeStartElement("文件列表"); // 开始根元素 <Blogs>
writer.writeStartElement("目录"); // 开始子元素 <Blog>
QString DirName = dir->currentPath();
writer.writeAttribute("Dirname", DirName); // 属性
foreach (QFileInfo info, infoList) {
QString fileName = info.fileName();
writer.writeTextElement("文件名", fileName);
}
writer.writeEndElement(); // 结束子元素 </Blog>
writer.writeEndElement(); // 结束根元素 </Blogs>
writer.writeEndDocument(); // 结束文档
file.close();
}
void Widget::readFile(){
QString strFile("fileList.xml");
QFile file(strFile);
if (!file.open(QFile::ReadOnly | QFile::Text)) { // 只写模式打开文件
qDebug() << QString("Cannot write file %1(%2).").arg(strFile).arg(file.errorString());
return;
}
QXmlStreamReader reader(&file);
while(!reader.atEnd()){
QXmlStreamReader::TokenType nType = reader.readNext();
if( nType == QXmlStreamReader::StartElement ){
QString nameStr = reader.name().toString();
QXmlStreamAttributes Attributes = reader.attributes();
if(Attributes.hasAttribute("Dirname")){
qDebug()<<Attributes.value("Dirname").toString();
}
if(QString::compare(nameStr,QStringLiteral("文件名")) == 0) {
reader.readNext();
qDebug() << QStringLiteral("文件名:%1").arg(reader.text().toString());
// qDebug() << QStringLiteral("文件名:%1").arg(reader.readElementText()); //该语句等效于上面两条语句
}
}
}
}
Widget::~Widget()
{
delete ui;
}