//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; } }
