<a target="_blank" href="http://bbs.qter.org/forum.php?mod=viewthread&tid=189">樓主</a>
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYWan5ibp1GZh9VZulGbu92Lc52bt12bj9CXldWYtl2LcNWa0FGdz9CXnJ3buIXZ0FnLzJmYvw1LcpDc0RHaiojIsJye.gif)
發表于 2013-5-21 22:00:51 | 檢視:
475| 回複: 0
使用dom建立和操作xml文檔
版權聲明
該文章原創于作者yafeilinux,轉載請注明出處!
導語
在上一節中我們用手寫的方法建立了一個xml文檔,并且用dom的方法對其進行了讀取。現在我們使用代碼來建立那個xml文檔,并且對它實作查找、更新、插入等操作。
環境:windows xp + qt 4.8.4+qtcreator 2.6.2
目錄
一、建立文檔
二、讀取文檔
三、添加節點
四、查找、删除、更新操作
正文
1.建立qt gui應用,項目名稱為mydom_2,基類為qmainwindow,類名為mainwindow。
2.完成後打開mydom_2.pro,然後将第一行代碼更改為:
qt += core gui xml
儲存該檔案。
3.輕按兩下mainwindow.ui進入設計模式,往界面上添加push button,label,line
edit,list widget等部件,設計界面如下圖所示。
4.完成後,打開mainwindow.cpp檔案,先包含頭檔案#include <qtxml>,然後在構造函數中添加如下代碼:
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"));
text = doc.createtextnode(tr("linux"));
text = doc.createtextnode(tr("yafei"));
qtextstream out(&file);
doc.save(out,4); // 将文檔儲存到檔案,4為子元素縮進字元數
file.close();
這裡先使用qdomdocument類在記憶體中生成了一棵dom樹,然後調用save()函數利用qtextstream文本流将dom樹儲存在了檔案中。在生成dom樹時主要使用了createelement()等函數來生成各種節點,然後使用appendchild()将各個節點依次追加進去。
5.打開main.cpp檔案,先包含頭檔案:#include <qtextcodec>,然後在main()函數第一行代碼後面添加如下代碼:
qtextcodec::setcodecfortr(qtextcodec::codecforname("utf8"));
6.運作程式,可以看到在建構目錄中生成了my.xml檔案,可以輕按兩下檢視該檔案的内容,效果如下圖所示。
下面我們讀取整個文檔的内容,并顯示在list widget部件上面,這裡用的就是上一節講到的内容。我們進入“檢視全部資訊”按鈕單擊信号槽,更改如下:
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();
//傳回根節點及其子節點的元素标記名
qdomelement docelem = doc.documentelement(); //傳回根元素
qdomnode n = docelem.firstchild();
//傳回根節點的第一個子節點
while(!n.isnull()) //如果節點不為空
if (n.iselement()) //如果節點是元素
{
qdomelement e = n.toelement(); //将其轉換為元素
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(); //下一個兄弟節點
}
運作程式,效果如下圖所示。
1.首先在設計模式,把書名和作者标簽後面的line edit部件的objectname分别更改為lineedit_title和lineedit_author。如下圖所示。
2.然後進入添加按鈕的單擊信号槽,添加如下代碼:
void mainwindow::on_pushbutton_4_clicked()
ui->listwidget->clear(); //我們先清空顯示,然後顯示“無法添加!”
ui->listwidget->additem(tr("無法添加!"));
if (!file.open(qiodevice::readonly)) return;
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;
// 我們獲得了最後一個孩子結點的編号,然後加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))
qtextstream out(&file);
doc.save(out,4);
//将文檔儲存到檔案,4為子元素縮進字元數
ui->listwidget->clear(); //最後更改顯示為“添加成功!”
ui->listwidget->additem(tr("添加成功!"));
這裡先用隻讀方式打開xml檔案,将其讀入doc中,然後關閉。我們将新的節點加入到最後面,并使其“編号”為以前的最後一個節點的編号加1。最後我們再用隻寫的方式打開xml檔案,将修改完的doc寫入其中。運作程式,效果如下圖所示。
再次檢視全部資訊,可以看到新的節點已經添加了,如下圖所示。
因為這三個功能都要先利用“編号”進行查找,是以我們放在一起實作。
1.首先将界面上“圖書編号”後面的line edit部件的objectname更改為lineedit_id。
2.在mainwindow.h檔案中添加public類型的函數聲明:
void doxml(constqstring operate);
我們使用這個函數來完成三種不同的操作,根據參數來判斷不同的操作。
3.然後到mainwindow.cpp中添加該函數的定義:
void mainwindow::doxml(const qstring operate)
ui->listwidget->additem(tr("沒有找到相關内容!"));
file.close();
qdomnodelist list = doc.elementsbytagname(tr("圖書"));
// 以标簽名進行查找
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(); //取出根節點
root.removechild(list.at(i)); //從根節點上删除該節點
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();
//找到它的所有子節點,就是“書名”和“作者”
child.at(0).toelement().firstchild().setnodevalue(ui->lineedit_title->text());
//将它子節點的首個子節點(就是文本節點)的内容更新
child.at(1).toelement().firstchild().setnodevalue(ui->lineedit_author->text());
return ;
doc.save(out,4);
//儲存文檔,4為子元素縮進字元數
ui->listwidget->additem(tr("更新成功!"));
else if(operate == "find") //如果是查找操作
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()
+"
}
4. 下面我們分别進入“查找”,“删除”,“更新”三個按鈕的單擊信号槽,更改如下:
// 查找
void mainwindow::on_pushbutton_clicked()
{
doxml("find");
// 删除
void mainwindow::on_pushbutton_2_clicked()
doxml("delete");
// 更新void
mainwindow::on_pushbutton_3_clicked()
doxml("update");
下面運作程式,查找操作結果如下圖所示。
然後對編号為1的圖書進行更新,效果如下圖所示。
更新後我們再次檢視所有内容。如下圖所示。
然後進行删除操作,如下圖所示。
删除後再次查詢所有内容。效果如下圖所示。
結語
涉及到的源碼:
kb, 下載下傳次數: 12)