Qt进行XML文件的读写
//Qt读写XML文档步骤
如下文所示:
<?xml version='1.0' encoding='UTF-8'?> <日销售清单> <日期 date="2022-02-14"> <时间 time="09-43-09"> <厂家>奥迪</厂家> <品牌>a6</品牌> <报价>39</报价> <数量>1</数量> <金额>39</金额> </时间> <时间 time="09-43-24"> <厂家>奥迪</厂家> <品牌>a6</品牌> <报价>39</报价> <数量>1</数量> <金额>39</金额> </时间> </日期> </日销售清单>
//写XML文档 1、首先创建一个XML文档类 //创建三个静态函数,方便调用 1):创建 createXML(QString filePath)来创建xml空文件,仅添加头部格式和文档根节点 用QFile file(filePath)函数来读取文件来检测文件是否存在,如果存爱就返回 如果不存在 bool isOk = file.open(QIODevice::WriteOnly);//以只写方式打开文件 isOk用来判断是否打开成功 打开成功的话: 第一步:创建XML文档对象,包含头文件#include <QDomDocument> //文件 QDomDocument doc; 第二部:创建xml头部格式 <?xml version="1.0" encoding="UTF-8"?> 包含头文件#include <QDomProcessingInstruction> QDomProcessingInstruction ins; ins = doc.createProcessingInstruction("xml","version=\'1.0\' encoding=\'UTF-8\'"); 第三步:将头部格式对象追加给它的父节点,也就是xml文档对象doc doc.appendChild(ins); 第四步:添加文档的根节点元素 QDomElement root = doc.createElement(QObject::tr("日销售清单")); doc.appendChild(root); 第五步:将文档对象元素保存到XML文件中去,保存前先将文本流和文件进行关联,并设置字符缩进 QTextStream stream(&file); //文本流关联文件 doc.save(stream,4); //4 缩进字符 第六步:将打开的文件进行关闭 file.close(); 2):创建appendXML(QString filepath,QStringList list);用来给创建好的根节点来追加子节点 用QFile file(filePath)函数来打开已存在的文件,并设置标志位 isOk 来判断是否打开成功 QFile file(filepath); bool isOk = file.open(QIODevice::ReadOnly); 如果打开成功 第一步:将打开的file文件和文档对象进行关联,并设置标志位 isOk 来判断是否关联成功 QDomDocument doc; isOk =doc.setContent(&file); 第二步:在关联成功情况下,将打开文件关闭,并获取根节点元素 file.close(); //获取根节点元素 QDomElement root = doc.documentElement(); 额外一步: 待会在插入节点元素之前,获取当日时间,作为标签的属性 //获取当前时间 QDateTime date = QDateTime::currentDateTime(); QString dateStr = date.toString("yyyy-MM-dd"); 第三步:判断当前根节点是否有子节点,分为有和没有两种情况 有子节点,直接执行写入XML的封装函数 if(lastEmt.attribute("date") == dateStr) { //在当天下面再添加一个 writeXML(doc,lastEmt,list); } 此处再进行一层判断,如上面的if语句,如果不存在相同日期节点元素,在后面进行添加 //创建日期子节点元素标签名 QDomElement dateEmt = doc.createElement("日期"); //创建日期属性名为date QDomAttr dateAttr = doc.createAttribute("date"); //设置属性值 dateAttr.setNodeValue(dateStr); //结点和属性关联 dateEmt.setAttributeNode(dateAttr); //把新节点添加到根节点 root.appendChild(dateEmt); //有效写入数据 writeXML(doc,dateEmt,list); 如果没有子节点,则创建子节点,然后执行写入操作 //创建日期子节点元素标签名 QDomElement dateEmt = doc.createElement("日期"); //创建日期属性名为date QDomAttr dateAttr = doc.createAttribute("date"); //设置属性值 dateAttr.setNodeValue(dateStr); //结点和属性关联 dateEmt.setAttributeNode(dateAttr); //把新节点添加到根节点 root.appendChild(dateEmt); //有效写入数据 writeXML(doc,dateEmt,list); 第四步:封装一个写入XML的函数writeXML 步骤同上,直接给出代码: //获取当前时间 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); 第五步:在writeXML中,为当前操作的节点添加文本信息 QDomElement factory = doc.createElement("厂家"); QDomElement brand = doc.createElement("品牌"); QDomElement price = doc.createElement("报价"); QDomElement num = doc.createElement("数量"); QDomElement total = doc.createElement("金额"); QDomText text = doc.createTextNode(list.at(0)); factory.appendChild(text); text = doc.createTextNode(list.at(1)); brand.appendChild(text); text = doc.createTextNode(list.at(2)); price.appendChild(text); text = doc.createTextNode(list.at(3)); num.appendChild(text); text = doc.createTextNode(list.at(4)); total.appendChild(text); timeEmt.appendChild(factory); timeEmt.appendChild(brand); timeEmt.appendChild(price); timeEmt.appendChild(num); timeEmt.appendChild(total);
domXML.h:
#ifndef DOMXML_H #define DOMXML_H #include <QString> #include <QStringList> #include <QDomDocument> #include<QDomElement> class DomXML { public: DomXML(); 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, QString &flist, QString &blist, QString &plist, QString &nlist, QString &tlist); }; #endif // DOMXML_H
domXML.cpp:
#include "domxml.h" #include <QFile> #include <QDomDocument> //文件 #include <QDomProcessingInstruction> //格式头 #include <QDomElement> //元素 #include <QTextStream> //文本流 #include <QDebug> #include <QDateTime> #pragma execution_character_set("utf-8") #define cout qDebug()<<"["<<__FILE__<<":"<<__LINE__<<"]" DomXML::DomXML() { } //创建xml文件 void DomXML::createXML(QString filePath) { QFile file(filePath); //关联文件名字 if(true == file.exists()) //如果存在就不创建 { cout<<"文件已经存在"; return; } else { //只写方式打开 bool isOk = file.open(QIODevice::WriteOnly); if(true == isOk) { //创建XML文档对象 QDomDocument doc; //创建xml头部格式 <?xml version="1.0" encoding="UTF-8"?> QDomProcessingInstruction ins; ins = doc.createProcessingInstruction("xml","version=\'1.0\' encoding=\'UTF-8\'"); //追加元素 doc.appendChild(ins); //根节点元素 QDomElement root = doc.createElement(QObject::tr("日销售清单")); doc.appendChild(root); //保存 QTextStream stream(&file); //文本流关联文件 doc.save(stream,4); //4 缩进字符 file.close(); //关闭文件 } else { cout<<"writeonly error"; return; } } } //追加节点 void DomXML::appendXML(QString filepath, QStringList list) { QFile file(filepath); bool isOk = file.open(QIODevice::ReadOnly); if(true==isOk) { //file和文档对象关联 QDomDocument doc; isOk =doc.setContent(&file); if(isOk) //如果关联成功 { file.close(); //获取根节点元素 QDomElement root = doc.documentElement(); //获取当前时间 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); //把新节点添加到根节点 root.appendChild(dateEmt); //有效写入数据 writeXML(doc,dateEmt,list); } } else { //创建日期子节点元素 QDomElement dateEmt = doc.createElement("日期"); //创建日期属性 QDomAttr dateAttr = doc.createAttribute("date"); //设置属性值 dateAttr.setNodeValue(dateStr); //结点和属性关联 dateEmt.setAttributeNode(dateAttr); //把新节点添加到根节点 root.appendChild(dateEmt); //有效写入数据 writeXML(doc,dateEmt,list); } //保存文件 isOk = file.open(QIODevice::WriteOnly); if(isOk) { QTextStream stream(&file); doc.save(stream,4); file.close(); } } else { cout<<"setContent error"; return; } } else { cout<<"readOnly error"; return; } } void DomXML::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); QDomElement factory = doc.createElement("厂家"); QDomElement brand = doc.createElement("品牌"); QDomElement price = doc.createElement("报价"); QDomElement num = doc.createElement("数量"); QDomElement total = doc.createElement("金额"); QDomText text = doc.createTextNode(list.at(0)); factory.appendChild(text); text = doc.createTextNode(list.at(1)); brand.appendChild(text); text = doc.createTextNode(list.at(2)); price.appendChild(text); text = doc.createTextNode(list.at(3)); num.appendChild(text); text = doc.createTextNode(list.at(4)); total.appendChild(text); timeEmt.appendChild(factory); timeEmt.appendChild(brand); timeEmt.appendChild(price); timeEmt.appendChild(num); timeEmt.appendChild(total); } void DomXML::readXML(QString filepath, QString &flist, QString &blist, QString &plist, QString &nlist, QString &tlist) { QFile file(filepath); bool isOk = file.open(QIODevice::ReadOnly); if(true == isOk) { //file和文档对象关联 QDomDocument doc; isOk =doc.setContent(&file); if(isOk) //如果关联成功 { //获取根节点 QDomElement root = doc.documentElement(); file.close(); QDateTime time = QDateTime::currentDateTime(); QString dateStr = time.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(); //厂家 } } else { cout<<"没有当前日期"; return; } } else { cout<<"没有子节点"; return; } } else { cout<<"setContent error"; return; } } else { cout<<"open error"; return; } }