Qt下讀寫XML格式檔案(使用QDomDocument類)
阿新 • • 發佈:2018-12-10
簡述
XML是一種標記語言,被設計用來結構化儲存以及傳輸資訊,是一種常用的文件資料結構。
就我個人而言,Qt下讀寫XML格式檔案可以有三種方法:
一是使用純C++的rapidxml開源庫。優點是速度快,媲美strlen()的速度;缺點是處理中文比較麻煩,編碼只有ANSI格式。
二是使用QXmlStreamReader類,適當結合QXmlQuery類。優點是靈活性強,節約記憶體;缺點是理解起來相對較難,還需要一點資料庫語言的知識。
三是使用QDomDocument類。是Qt下讀寫xml檔案傳統而普遍的做法,缺點就是如果讀寫的檔案很大,會消耗大量的記憶體空間。
QDomDocument類可以理解為一個QFile,這個類的物件代表了整個檔案,通常也是一個xml檔案的主節點。還需使用到的類有QDomNode(節點基類)、QDomElement(節點類)、QDomText(內容)、QDomAttr(屬性)、QDomProcessingInstruction(檔案頭)。
程式碼之路
讀寫一個使用者名稱檔案"user.xml",檔案內容如下:
<?xml version = "1.0" encoding = "UTF-8"?> <ALL> <DATA> <Name>1</Name> <Password>12</Password> <Describe>123</Describe> <Flag>1</Flag> </DATA> <DATA> <Name>2</Name> <Password>22</Password> <Describe>234</Describe> <Flag>1</Flag> </DATA> </ALL>
讀取上述內容的xml檔案到一個結構體中
//使用者資訊結構體
struct UserStruct
{
QString username;
QString password;
QString decribe;
int flag; //使用者許可權
void clear()
{
username = "";
password = "";
describe = "";
flag = 1;
}
};
讀xml格式函式程式碼如下:
void readUserxml() { UserStruct tmpInfo; QFile file(filename); if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) { return; } QDomDocument doc; //xml格式檔案 if (!doc.setContent(&file)) { file.close(); return; } file.close(); QDomElement root = doc.documentElement(); //節點 ALL if (!root.isNull()) { QDomNode node_a = root.firstChild(); //節點DATA while (!node_a.isNull()) { QDomElement node_all = node_a.toElement(); //QDomnode轉成QDomElement if (!node_all.isNull()) { tmpInfo.clear(); //清空 QDomElement n_name = node_all.firstChildElement("Name"); //Name節點 if (!n_name.isNull()) { tmpInfo.username = n_name.text(); } QDomElement n_passwd = node_all.firstChildElement("Password"); //Password節點 if (!n_passwd.isNull()) { tmpInfo.password = n_passwd.text(); } QDomElement n_describe = node_all.firstChildElement("Describe"); //Describe節點 if (!n_describe.isNull()) { tmpInfo.describe = n_describe.text(); } QDomElement n_flag = node_all.firstChildElement("Flag"); //Flag節點 if (!n_flag.isNull()) { tmpInfo.flag = n_flag.text().toInt(); } // //加入vector // UserInfo.push_back(tmpInfo); } node_a = node_a.nextSibling(); //讀取下一個DATA節點 } } }
寫XML格式檔案
void writeUserxml()
{
//寫入xml
QFile file(Filename);
if (!file.open(QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate))
{
return;
}
QDomDocument doc;
QDomProcessingInstruction instruction;
instruction = doc.createProcessingInstruction("xml", "version = \"1.0\" encoding = \"UTF-8\"");
doc.appendChild(instruction); //寫入檔案頭
QDomElement root = doc.createElement("ALL");
doc.appendChild(root);
// UserStruct tmp;
// tmp.username = "11";
// tmp.password = "1234";
// tmp.describe = "321";
// tmp.flag = 1;
// UserInfo.push_back(tmp);
int sum = UserInfo.size();
// struct UserStruct
// {
// QString username;
// QString password;
// QString describe;
// int flag;
// };
for (int i = 0; i < sum; ++i)
{
QDomElement node_data = doc.createElement("DATA");
QDomElement node_name = doc.createElement("Name");
QDomElement node_passwd = doc.createElement("Password");
QDomElement node_describe = doc.createElement("Describe");
QDomElement node_flag = doc.createElement("Flag");
node_name.appendChild(doc.createTextNode(UserInfo[i].username));
node_passwd.appendChild(doc.createTextNode(UserInfo[i].password));
node_describe.appendChild(doc.createTextNode(UserInfo[i].describe));
node_flag.appendChild(doc.createTextNode(QString::number(UserInfo[i].flag)));
node_data.appendChild(node_name);
node_data.appendChild(node_passwd);
node_data.appendChild(node_describe);
node_data.appendChild(node_flag);
root.appendChild(node_data);
}
QTextStream out(&file);
doc.save(out, 4); //寫入檔案中
file.close();
}
例子中沒有涉及到節點屬性,下面補充一下節點屬性的寫入:
QDomAttr atr = doc.createAttribute("id");
atr.setValue(str_id);
node_date.setAttributeNode(atr);
總結
Qt下使用QDomdocument類書寫xml程式碼量相對不少,但是思路還是很清晰的。