[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档
生活随笔
收集整理的這篇文章主要介紹了
[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
[Qt教程]?第28篇 XML(二)使用DOM創(chuàng)建和操作XML文檔
??|?查看: 475|?回復(fù): 0| 使用DOM創(chuàng)建和操作XML文檔 版權(quán)聲明 該文章原創(chuàng)于作者yafeilinux,轉(zhuǎn)載請注明出處! 導(dǎo)語 在上一節(jié)中我們用手寫的方法建立了一個XML文檔,并且用DOM的方法對其進(jìn)行了讀取。現(xiàn)在我們使用代碼來創(chuàng)建那個XML文檔,并且對它實現(xiàn)查找、更新、插入等操作。 環(huán)境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2 目錄 一、創(chuàng)建文檔 二、讀取文檔 三、添加節(jié)點 四、查找、刪除、更新操作 正文 一、創(chuàng)建文檔 1.新建Qt Gui應(yīng)用,項目名稱為myDom_2,基類為QMainWindow,類名為MainWindow。 2.完成后打開myDom_2.pro,然后將第一行代碼更改為: QT? ?? ??+= core??gui? ?xml 保存該文件。 3.雙擊mainwindow.ui進(jìn)入設(shè)計模式,往界面上添加Push Button,Label,Line Edit,List Widget等部件,設(shè)計界面如下圖所示。 4.完成后,打開mainwindow.cpp文件,先包含頭文件#include?<QtXml>,然后在構(gòu)造函數(shù)中添加如下代碼: QFile?file("my.xml"); //?只寫方式打開,并清空以前的信息 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) return ; QDomDocument?doc; QDomProcessingInstruction?instruction;??//添加處理指令 instruction = doc.createProcessingInstruction("xml","version=\"1.0\"encoding=\"UTF-8\""); doc.appendChild(instruction); QDomElement?root = doc.createElement(tr("書庫")); doc.appendChild(root); //添加根元素 //?添加第一個book元素及其子元素 QDomElement?book = doc.createElement(tr("圖書")); QDomAttr?id = doc.createAttribute(tr("編號")); QDomElement?title = doc.createElement(tr("書名")); QDomElement?author = doc.createElement(tr("作者")); QDomText?text; id.setValue(tr("1")); book.setAttributeNode(id); text = doc.createTextNode(tr("Qt")); title.appendChild(text); text = doc.createTextNode(tr("shiming")); author.appendChild(text); book.appendChild(title); book.appendChild(author); root.appendChild(book); //?添加第二個book元素及其子元素 book = doc.createElement(tr("圖書")); id = doc.createAttribute(tr("編號")); title = doc.createElement(tr("書名")); author = doc.createElement(tr("作者")); id.setValue(tr("2")); book.setAttributeNode(id); text = doc.createTextNode(tr("Linux")); title.appendChild(text); text = doc.createTextNode(tr("yafei")); author.appendChild(text); book.appendChild(title); book.appendChild(author); root.appendChild(book); QTextStream?out(&file); doc.save(out,4); //?將文檔保存到文件,4為子元素縮進(jìn)字符數(shù) file.close(); 這里先使用QDomDocument類在內(nèi)存中生成了一棵DOM樹,然后調(diào)用save()函數(shù)利用QTextStream文本流將DOM樹保存在了文件中。在生成DOM樹時主要使用了createElement()等函數(shù)來生成各種節(jié)點,然后使用appendChild()將各個節(jié)點依次追加進(jìn)去。 5.打開main.cpp文件,先包含頭文件:#include?<QTextCodec>,然后在main()函數(shù)第一行代碼后面添加如下代碼: QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8")); 6.運行程序,可以看到在構(gòu)建目錄中生成了my.xml文件,可以雙擊查看該文件的內(nèi)容,效果如下圖所示。 二、讀取文檔 下面我們讀取整個文檔的內(nèi)容,并顯示在List Widget部件上面,這里用的就是上一節(jié)講到的內(nèi)容。我們進(jìn)入“查看全部信息”按鈕單擊信號槽,更改如下: void?MainWindow::on_pushButton_5_clicked() { ? ??ui->listWidget->clear(); //先清空顯示 ? ??QFile?file("my.xml"); ? ??if?(!file.open(QIODevice::ReadOnly))?return?; ? ??QDomDocument?doc; ? ??if?(!doc.setContent(&file)) ? ??{ ? ?? ??file.close(); ? ?? ??return?; ? ??} ? ? file.close(); ? ??//返回根節(jié)點及其子節(jié)點的元素標(biāo)記名 ? ??QDomElement?docElem?=?doc.documentElement();??//返回根元素 ? ??QDomNode?n?=?docElem.firstChild();? ?//返回根節(jié)點的第一個子節(jié)點 ? ??while(!n.isNull())??//如果節(jié)點不為空 ? ??{ ? ?? ???if?(n.isElement())?//如果節(jié)點是元素 ? ?? ??{ ? ?? ?? ???QDomElement?e?=?n.toElement();?//將其轉(zhuǎn)換為元素 ? ?? ?? ???ui->listWidget->addItem(e.tagName() +e.attribute(tr("編號"))); ? ?? ?? ???QDomNodeList?list?=?e.childNodes(); ? ?? ?? ???for(int?i=0;?i<list.count();?i++) ? ?? ?? ???{ ? ?? ?? ?? ?? ??QDomNode?node?=?list.at(i); ? ?? ?? ?? ?? ??if(node.isElement()) ? ?? ?? ?? ?? ?? ??ui->listWidget->addItem("? ?" +node.toElement().tagName() ? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?+" : "+node.toElement().text()); ? ?? ?? ???} ? ?? ??} ? ?? ??n?=?n.nextSibling();??//下一個兄弟節(jié)點 ? ??} } 運行程序,效果如下圖所示。 三、添加節(jié)點 1.首先在設(shè)計模式,把書名和作者標(biāo)簽后面的Line Edit部件的objectName分別更改為lineEdit_title和lineEdit_author。如下圖所示。 ? 2.然后進(jìn)入添加按鈕的單擊信號槽,添加如下代碼: void?MainWindow::on_pushButton_4_clicked() { ? ??ui->listWidget->clear();?//我們先清空顯示,然后顯示“無法添加!” ? ??ui->listWidget->addItem(tr("無法添加!")); ? ??QFile?file("my.xml"); ? ??if?(!file.open(QIODevice::ReadOnly))?return; ? ??QDomDocument?doc; ? ??if?(!doc.setContent(&file)) ? ??{ ? ?? ??file.close(); ? ?? ??return; ? ??} ? ??file.close(); ? ??QDomElement?root?=?doc.documentElement(); ? ??QDomElement?book?=?doc.createElement(tr("圖書")); ? ??QDomAttr?id?=?doc.createAttribute(tr("編號")); ? ??QDomElement?title?=?doc.createElement(tr("書名")); ? ??QDomElement?author?=?doc.createElement(tr("作者")); ? ??QDomText?text; ? ??//?我們獲得了最后一個孩子結(jié)點的編號,然后加1,便是新的編號 ? ??QString?num?=?root.lastChild().toElement().attribute(tr("編號")); ? ??int?count?=?num.toInt()?+1; ? ??id.setValue(QString::number(count)); ? ??book.setAttributeNode(id); ? ??text?=?doc.createTextNode(ui->lineEdit_title->text()); ? ??title.appendChild(text); ? ??text?=?doc.createTextNode(ui->lineEdit_author->text()); ? ??author.appendChild(text); ? ??book.appendChild(title); ? ??book.appendChild(author); ? ??root.appendChild(book); ? ??if(!file.open(QIODevice::WriteOnly?|?QIODevice::Truncate)) ? ?? ??return?; ? ??QTextStream?out(&file); ? ??doc.save(out,4);? ?//將文檔保存到文件,4為子元素縮進(jìn)字符數(shù) ? ??file.close(); ? ??ui->listWidget->clear();?//最后更改顯示為“添加成功!” ? ??ui->listWidget->addItem(tr("添加成功!")); } 這里先用只讀方式打開XML文件,將其讀入doc中,然后關(guān)閉。我們將新的節(jié)點加入到最后面,并使其“編號”為以前的最后一個節(jié)點的編號加1。最后我們再用只寫的方式打開XML文件,將修改完的doc寫入其中。運行程序,效果如下圖所示。 再次查看全部信息,可以看到新的節(jié)點已經(jīng)添加了,如下圖所示。 四、查找、刪除、更新操作 因為這三個功能都要先利用“編號”進(jìn)行查找,所以我們放在一起實現(xiàn)。 1.首先將界面上“圖書編號”后面的Line Edit部件的objectName更改為lineEdit_id。 2.在mainwindow.h文件中添加public類型的函數(shù)聲明: ? ??void?doXml(constQString?operate); 我們使用這個函數(shù)來完成三種不同的操作,根據(jù)參數(shù)來判斷不同的操作。 3.然后到mainwindow.cpp中添加該函數(shù)的定義: void?MainWindow::doXml(const?QString?operate) { ? ??ui->listWidget->clear(); ? ??ui->listWidget->addItem(tr("沒有找到相關(guān)內(nèi)容!")); ? ??QFile?file("my.xml"); ? ??if?(!file.open(QIODevice::ReadOnly))?return?; ? ??QDomDocument?doc; ? ??if?(!doc.setContent(&file)) ? ??{ ? ?? ??file.close(); ? ?? ??return?; ? ??} ??file.close(); ? ??QDomNodeList?list?=?doc.elementsByTagName(tr("圖書")); ? ??//?以標(biāo)簽名進(jìn)行查找 ? ??for(int?i=0;?i<list.count();?i++) ? ??{ ? ?? ??QDomElement?e?=?list.at(i).toElement(); ? ?? ??//?如果元素的“編號”屬性值與我們所查的相同 ? ?? ??if(e.attribute(tr("編號"))?==?ui->lineEdit_id->text()) ? ?? ??{ ? ?? ?? ?? ?//?如果元素的“編號”屬性值與我們所查的相同 ? ?? ?? ???if(operate?==?"delete")??//如果是刪除操作 ? ?? ?? ???{ ? ?? ?? ?? ?? ??QDomElement?root?=?doc.documentElement();?//取出根節(jié)點 ? ?? ?? ?? ?? ??root.removeChild(list.at(i));??//從根節(jié)點上刪除該節(jié)點 ? ?? ?? ?? ?? ??QFile?file("my.xml");? ???//保存更改 ? ?? ?? ??if(!file.open(QIODevice::WriteOnly?|?QIODevice::Truncate)) ?return ; ? ?? ?? ?? ?? ??QTextStream?out(&file); ? ?? ?? ?? ?? ??doc.save(out,4); ? ?? ?? ?? ?? ??file.close(); ? ?? ?? ?? ?? ??ui->listWidget->clear(); ? ?? ?? ?? ?? ??ui->listWidget->addItem(tr("刪除成功!")); ? ?? ?? ???} ? ?? ?? ???else?if(operate?==?"update")??//如果是更新操作 ? ?? ?? ???{ ? ?? ?? ?? ?? ??QDomNodeList?child?=?list.at(i).childNodes(); ? ?? ?? ?? ?? ??//找到它的所有子節(jié)點,就是“書名”和“作者” ? ?? ?? ?? ?? ??child.at(0).toElement().firstChild().setNodeValue(ui->lineEdit_title->text()); ? ?? ?? ?? ?? ??//將它子節(jié)點的首個子節(jié)點(就是文本節(jié)點)的內(nèi)容更新 ? ?? ?? ?? ?? ??child.at(1).toElement().firstChild().setNodeValue(ui->lineEdit_author->text()); ? ?? ?? ?? ?? ??QFile?file("my.xml");? ???//保存更改 ? ?? ?? ??if(!file.open(QIODevice::WriteOnly?|?QIODevice::Truncate)) ? ???return ; ? ?? ?? ?? ?? ??QTextStream?out(&file); ? ?? ?? ?? ?? ??doc.save(out,4);? ?//保存文檔,4為子元素縮進(jìn)字符數(shù) ? ?? ?? ?? ?? ??file.close(); ? ?? ?? ?? ?? ??ui->listWidget->clear(); ? ?? ?? ?? ?? ??ui->listWidget->addItem(tr("更新成功!")); ? ?? ?? ???} ? ?? ?? ???else?if(operate?==?"find")??//如果是查找操作 ? ?? ?? ???{ ? ?? ?? ?? ?? ??ui->listWidget->clear(); ? ?? ?? ?? ?? ??ui->listWidget->addItem(e.tagName()+e.attribute(tr("編號"))); ? ?? ?? ?? ?? ??QDomNodeList?list?=?e.childNodes(); ? ?? ?? ?? ?? ??for(int?i=0;?i<list.count();?i++) ? ?? ?? ?? ?? ?{ ? ?? ?? ?? ?? ?? ???QDomNode?node?=?list.at(i); ? ?? ?? ?? ?? ?? ???if(node.isElement()) ? ?? ?? ?? ?? ?? ?? ?? ?ui->listWidget->addItem("? ?"+node.toElement().tagName() ? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?+" : "+node.toElement().text()); ? ?? ?? ?? ?? ??} ? ?? ?? ???} ? ?? ??} ? ??} } 4.?下面我們分別進(jìn)入“查找”,“刪除”,“更新”三個按鈕的單擊信號槽,更改如下: //?查找 void?MainWindow::on_pushButton_clicked() {? ?? ? ? doXml("find"); } //?刪除 void?MainWindow::on_pushButton_2_clicked() {? ?? ? ?? ?doXml("delete"); } //?更新void? MainWindow::on_pushButton_3_clicked() {? ?? ? ?? ?doXml("update"); } 下面運行程序,查找操作結(jié)果如下圖所示。 然后對編號為1的圖書進(jìn)行更新,效果如下圖所示。 更新后我們再次查看所有內(nèi)容。如下圖所示。 然后進(jìn)行刪除操作,如下圖所示。 刪除后再次查詢所有內(nèi)容。效果如下圖所示。 結(jié)語 通過本節(jié)的例子可以看到使用DOM可以很方便的進(jìn)行XML文檔的隨機(jī)訪問,這也是它最大的優(yōu)點。關(guān)于更多更詳細(xì)的內(nèi)容可以參考《Qt Creator快速入門》的相關(guān)章節(jié)。 涉及到的源碼:??myDom_2.zip?? |
總結(jié)
以上是生活随笔為你收集整理的[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Qt教程] 第26篇 数据库(六)SQ
- 下一篇: 【Qt】XML简介