QT中的XML定义简介
QDomDocument
//QDomDocument类表示一个XML文档。
QDomElement
//QDomElement类表示DOM树中的一个元素。
QDomAttr
//QDomAttr类表示QDomElement的一个属性。
QDomNodeList
//QDomNodeList类是QDomNode对象的列表。
QDomText
//QDomText类表示已解析的XML文档中的文本数据。
#define cout qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]"
qDebug()定义成cout并且显示文件,行信息
1. XML 文档实例
//第一行是 XML 声明。它定义 XML 的版本 (1.0) 和所使用的编码 (utf-8)
<?xml version='1.0' encoding='utf-8'?> //XML 声明
<日销售清单> //描述文档的根元素
<日期 date="2020-08-02"> //描述文档的子节点元素
<时间 time="14:18:27"> //描述文档的子节点元素
<厂家>一汽大众</厂家> //描述文档的子元素
<品牌>一汽大众</品牌>
<报价>10</报价>
<数量>1</数量>
<金额>10</金额>
</时间>
</日期>
</日销售清单> //定义根元素的结尾
2. QT中创建XML
void DemoXml::createXML(QString filePath)
{
QFile file(filePath);
if(file.exists() == true) //判断文件是否存在
{
cout << "文件已存在";
}
else
{
bool isOK = file.open(QIODevice::WriteOnly);
if(isOK == true)
{
//创建xml文档
QDomDocument doc;
//XML处理说明
QDomProcessingInstruction ins;
ins = doc.createProcessingInstruction("xml","version=\'1.0\' encoding=\'utf-8\'"); //XML 声明
doc.appendChild(ins); //在doc后追加元素
//生成<?xml version='1.0' encoding='utf-8'?>
//根节点元素
QDomElement root = doc.createElement("日销售清单");
doc.appendChild(root); //在doc后追加元素
//保存
QTextStream stream(&file); //文本流关联文件,用来生成XML格式的内容
doc.save(stream,4) ; //存入file文件中,4-缩进字符
file.close();
//生成内容 <日销售清单/>
}
else
{
cout << "WriteOnly error";
return ;
}
}
}
3. 创建时间节点
void DemoXml::appendXML(QString filePath, QStringList list)
{
QFile file(filePath);
bool isOk = file.open(QIODevice::ReadOnly);
if(isOk == true) //判断文件是否打开成功
{
//file和xml文档对象关联,关联后才能使用
QDomDocument doc;
isOk = doc.setContent(&file); //判断是否关联成功
if(isOk)
{
file.close();
//获取根节点
QDomElement root = doc.documentElement();
//这个XML文件以天数为分界,获取当前时间与XML文件时间比较
//<日期 date="2020-08-02">
QDateTime date = QDateTime::currentDateTime();
QString dateStr = date.toString("yyyy-MM-dd");
if(root.hasChildNodes()) //如果有子节点
{
//查找最后一个子节点
QDomElement lastEmt = root.lastChildElement();
if(lastEmt.attribute("date") == dateStr)//与当前的日期比较
{
writeXML(doc,lastEmt,list);//如果有当前日期就不需要创建
}
else//如果不是今天的时间,就创建新日期
{
//创建日期子节点元素
QDomElement dateEmt = doc.createElement("日期");
//创建date属性
QDomAttr dateAttr = doc.createAttribute("date");
//设定属性的值
dateAttr.setNodeValue(dateStr);
//节点和属性关联
dateEmt.setAttributeNode(dateAttr);
//把日期节点追加到根节点上
//<日销售清单>
// <日期 date="2020-08-03">
root.appendChild(dateEmt);
//创建完时间节点后,再写入数据
writeXML(doc,dateEmt,list);
}
}
else //如果没有日期子节点就创建,步骤和上面一样
{
//创建日期子节点元素
QDomElement dateEmt = doc.createElement("日期");
//创建date属性
QDomAttr dateAttr = doc.createAttribute("date");
//设定属性的值
dateAttr.setNodeValue(dateStr);
//节点和属性关联
dateEmt.setAttributeNode(dateAttr);
//把日期节点追加到根节点上
//<日销售清单>
// <日期 date="2020-08-03">
root.appendChild(dateEmt);
//创建完时间节点后,再写入数据
writeXML(doc,dateEmt,list);
}
//保存文件
isOk = file.open(QIODevice::WriteOnly);
if(isOk)
{
QTextStream stream(&file);//文本流关联文件,用来生成XML格式的内容
doc.save(stream,4);
}
}
else
{
cout << "setContent error";
}
}
else
{
cout << "ReadOnly error";
}
}
4. 写入XML文件
void DemoXml::writeXML(QDomDocument &doc, QDomElement &root, QStringList &list)
{
//获取当前时间
QDateTime time = QDateTime::currentDateTime();
QString timeStr = time.toString("hh:mm:ss");
//创建时间节点元素
QDomElement timeEmt = doc.createElement("时间");
//创建属性
QDomAttr timeAttr = doc.createAttribute("time");
//给属性设置值
timeAttr.setNodeValue(timeStr);
//时间节点元素和属性关联
timeEmt.setAttributeNode(timeAttr);
//把时间节点追击到日期节点后面
root.appendChild(timeEmt);
//<日销售清单>
// <日期 date="2020-08-03">
// <时间 time="09:40:19">
//利用容器快速写入到XML文件中
std::vector<QDomElement> car;
//doc.createElement() 创建元素
car.push_back(doc.createElement("厂家"));
car.push_back(doc.createElement("品牌"));
car.push_back(doc.createElement("报价"));
car.push_back(doc.createElement("数量"));
car.push_back(doc.createElement("金额"));
for(int i=0;i<car.size();i++)
{
QDomText text = doc.createTextNode(list.at(i)); //写入信息
car[i].appendChild(text); //将text中的信息写入
timeEmt.appendChild(car[i]); //追加到时间节点后面
//这里是子元素不是节点
//<厂家>一汽大众</厂家>
}
}
5. 读取XML文件内容
void DemoXml::readXML(QString filePath, std::vector<std::vector<QString>> &carVector)
{
QFile file(filePath);
bool isOk = file.open(QIODevice::ReadOnly);
if(isOk == true)//打开成功
{
//file和xml文档对象关联
QDomDocument doc;
isOk = doc.setContent(&file);
if(isOk)
{
//获取根节点
QDomElement root = doc.documentElement();
file.close();
//获取当前时间
QDateTime date = QDateTime::currentDateTime();
QString dateStr = date.toString("yyyy-MM-dd");
if(root.hasChildNodes()) //判断有没有子节点
{
QDomElement lastEmt = root.lastChildElement();//获取最后一个子节点
if(lastEmt.attribute("date") == dateStr) //判断最后一个子节点是不是当天的日期
{
//找出当前日期下所有时间子节点,读取的是当天的所有交易
QDomNodeList list = lastEmt.childNodes();
for(int i=0;i<list.size();i++)
{
//读取每个时间节点的内容
QDomNodeList subList = list.at(i).toElement().childNodes();
std::vector<QString> test;
test.push_back(subList.at(0).toElement().text());//转换成QString格式
test.push_back(subList.at(1).toElement().text());
test.push_back(subList.at(2).toElement().text());
test.push_back(subList.at(3).toElement().text());
test.push_back(subList.at(4).toElement().text());
carVector.push_back(test);
}
}
else //如果不是当天日期就不读取
{
cout << "没有当天日期";
return ;
}
}
else //没有子节点不读取
{
cout << "没有子节点";
return;
}
}
else //关联失败不读取
{
cout << "setContent error";
return ;
}
} //文件打开失败不读取
else
{
cout << "ReadOnly error";
return ;
}
}
6. 头文件
类的静态成员(变量和方法)属于类本身,在类加载的时候就会分配内存,可以通过类名直接去访问;非静态成员(变量和方法)属于类的对象,所以只有在类的对象产生(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。
#include <QString>
#include <QStringList>
#include <QDomDocument>
#include <QDomElement>
class DemoXml
{
public:
DemoXml();
//静态成员函数的作用在于:调用这个函数不会访问或者修改任何对象(非static)数据成员
static void createXML(QString filePath);//创建XML文件
static void appendXML(QString filePath,QStringList list);//是否需要添加日期内容
static void writeXML(QDomDocument &doc,QDomElement &root,QStringList list);//写入XML文件
static void readXML(QString filePath,std::vector<std::vector<QString>> &carVector); //读取XML文件
};
7. 测试
//DemoXml中的函数定义为static,可以直接调用
DemoXml::createXML("../demo.xml"); //创建一个demo.xml文件
QStringList list;
list << "二汽神龙" << "毕加索" << "39" << "1" << "39";
DemoXml::appendXML("../demo.xml",list); //写入数据
std::vector<std::vector<QString>> carString;
DemoXml::readXML("../demo.xml",carString); //读取数据
for(int i=0;i<carString.size();i++)
{
QString str = QString("%1:%2:卖出了%3,单价为%4,总价为%5")
.arg(carString[i][0])
.arg(carString[i][1])
.arg(carString[i][3])
.arg(carString[i][2])
.arg(carString[i][4]);
qDebug() << str;
}
//"二汽神龙:毕加索:卖出了1,单价为39,总价为39"
//读取成功
}