Qt:用Dom方式讀寫xml檔案
阿新 • • 發佈:2019-02-18
網上有不少介紹Dom方式讀寫xml檔案,大部分給出的程式碼都不夠完整。這裡通過我做的的一個例子做一個完整的總結。XML檔案格式如下
寫檔案:<?xml version="1.0" encoding="UTF-8"?> <RootSkeletonData> <RootNode> <X>77.3122</X> <Y>80.0328</Y> <Z>0</Z> </RootNode> <RootNode> <X>77.3154</X> <Y>80.0902</Y> <Z>0.5</Z> </RootNode> <RootSkeletonData>
簡述:所有的標籤只能有QDomDocument通過createElement來建立,其生成一個QDomElement標籤元素。按照自己規劃的樹形結構,決定生成的新標籤到底要加入(appendChild)哪一個標籤下面。通過createTextNode可以建立一個文字標籤bool SkeletonWriter::saveSkeletonData(QString filename,QList<RootNode> &nodes) { //--[1]引數檢測 if(nodes.isEmpty()) { qDebug()<<"Error:skeleton Data is null!"; return false; } QFile file(filename); if(!file.open(QFile::WriteOnly|QFile::Text)) { qDebug()<<"Error: Cannot write file:"<<filename; return false; } //[1] //[2] --建立一個根目錄 QDomElement root=doc->createElement("RootSkeletonData"); doc->appendChild(root); //[2] //[3] --建立每一個根結點元素 for(int i=0;i<nodes.size();++i) createNodeElement(&root,&nodes[i]); //[3] //[4] --xml檔案頭 QDomNode xmlnode=doc->createProcessingInstruction("xml", "version=\"1.0\"encoding=\"UTF-8\""); doc->insertBefore(xmlnode,doc->firstChild()); //[4] //[5] --儲存 QTextStream out(&file); out.setCodec("UTF-8"); doc->save(out,4,QDomNode::EncodingFromTextStream); //[5] file.close(); return true; } void SkeletonWriter::createNodeElement(QDomElement *element, RootNode *node) { // --[1]create nodeelement QDomElement g_node=doc->createElement("RootNode"); element->appendChild(g_node); //[1] // --[2] create 各個座標值 QVector3D center=node->getCentroid(); QDomElement nodeX=doc->createElement("X"); g_node.appendChild(nodeX); QDomText X_Text=doc->createTextNode(QString::number(center.x())); nodeX.appendChild(X_Text); QDomElement nodeY=doc->createElement("Y"); g_node.appendChild(nodeY); QDomText Y_Text=doc->createTextNode(QString::number(center.y())); nodeY.appendChild(Y_Text); QDomElement nodeZ=doc->createElement("Z"); g_node.appendChild(nodeZ); QDomText Z_Text=doc->createTextNode(QString::number(center.z())); nodeZ.appendChild(Z_Text); //[2] }
讀檔案:
bool SkeletonReader::setFileName(QString filename) { //[1] --檔案讀取檢測 QFile file(filename); if(!file.open(QFile::ReadOnly|QFile::Text)) { qDebug()<<"Error:Cannot readfile!"<<filename; return false; } //[1] //[2] --xml檔案解析檢測 QDomDocument doc; QString errorStr; int errorLine; int errorColumn; if(!doc.setContent(&file,false,&errorStr,&errorLine,&errorColumn)) { qDebug()<<"Error:Parse error at line:"<<errorLine<<"," <<"at column:"<<errorColumn<<":" <<errorStr; file.close(); return false; } QDomElement root=doc.documentElement(); rootTagName=root.tagName(); if(root.tagName()!="RootSkeletonData") { qDebug()<<"Not a rootSkeleton data file!"; file.close(); return false; } parseNodeElement(&root); file.close(); return true; } void SkeletonReader::parseNodeElement(const QDomElement *element) { QDomNode child =element->firstChild(); while(!child.isNull()) { parseCenterElement(&child.toElement()); child=child.nextSibling(); } } void SkeletonReader::parseCenterElement(const QDomElement *element) { QDomNode child =element->firstChild(); double center[3]; while(!child.isNull()) { if(child.toElement().tagName()=="X") center[0]=child.toElement().text().toDouble(); if(child.toElement().tagName()=="Y") center[1]=child.toElement().text().toDouble(); if(child.toElement().tagName()=="Z") center[2]=child.toElement().text().toDouble(); child=child.nextSibling(); } RootNode node; node.setCentroid(center); m_nodes<<node; }
簡述:讀檔案 注意前面一系列的引數檢測。這裡買面反覆用的的幾個Dom相關的類分別是:QDomDocment、QDomNode、QDomElement、QDomText
其中QDomDocument類表示一個XML文件。該類可以生成新結點
QDomNode類是DOM樹中所有節點的基類。代表結點 該類儲存了結點之間的樹型拓撲關係
QDomElement類表示Element型別結點。存放元素類資料(一對標籤組成)其繼承自QDomNode
QDomText類表示Text型別節點 存放文字資料 繼承自QDomNode
理清這幾個類就基本可以完成一個XML檔案的讀寫了
參考文獻: