<a target="_blank" href="http://bbs.qter.org/forum.php?mod=viewthread&tid=188">樓主</a>

發表于 2013-5-21 21:14:28 | 檢視:
1001| 回複: 14
使用dom讀取xml文檔
版權聲明
該文章原創于作者yafeilinux,轉載請注明出處!
導語
xml(extensiblemarkup language,可擴充标記語言),是一種類似于html的标記語言,但它的設計目的是用來傳輸資料,而不是顯示資料。xml的标簽沒有被預定義,使用者需要在使用時自行進行定義。xml是w3c(網際網路聯盟)的推薦标準。相對于資料庫表格的二維表示,xml使用的樹形結構更能表現出資料的包含關系,作為一種文本檔案格式,xml簡單明了的特性使得它在資訊存儲和描述領域非常流行。
在qt中提供了qtxml子產品來進行xml文檔的處理,我們在qt幫助中輸入關鍵字qtxml
module,可以看到該子產品的類表。這裡主要提供了三種解析方法: dom方法,可以進行讀寫;sax方法,可以進行讀取;基于流的方法,分别使用qxmlstreamreader和qxmlstreamwriter進行讀取和寫入。要在項目中使用qtxml子產品,還需要在項目檔案(.pro檔案)中添加qt
+= xml一行代碼。這一節我們先來講解一下dom的方法。
環境:windows xp + qt 4.8.4+qtcreator 2.6.2
目錄
一、xml文檔示例
二、使用dom讀取xml文檔内容
正文
下面是一個規範的xml文檔:
<?xml version="1.0"encoding="utf-8"?>
<library>
<book id="01">
<title>qt</title>
<author>shiming</author>
</book>
<book id="02">
<title>linux</title>
<author>yafei</author>
</book>
</library>
每個xml文檔都由xml說明(或者稱為xml序言)開始,它是對xml文檔處理的環境和要求的說明,比如這裡的<?xmlversion="1.0"
encoding="utf-8"?>,其中xml version=“1.0”,表明使用的xml版本号,這裡字母是區分大小寫的;encoding=“utf-8”是使用的編碼,指出文檔是使用何種字元集建立的,預設值為unicode編碼。xml文檔内容由多個元素組成,一個元素由起始标簽<标簽名>和終止标簽</标簽名>以及兩個标簽之間的内容組成,而文檔中第一個元素被稱為根元素,比如這裡的<library></library>,xml文檔必須有且隻有一個根元素。元素的名稱是區分大小寫的,元素還可以嵌套,比如這裡的library、book、title和author等都是元素。元素可以包含屬性,用來描述元素的相關資訊,屬性名和屬性值在元素的起始标簽中給出,格式為<元素名 屬性名=“屬性值”>,如<book
id=“01”>,屬性值必須在單引号或者雙引号中。在元素中可以包含子元素,也可以隻包含文本内容,比如這裡的<title>qt</title>中的qt就是文本内容。
dom(document object model,即文檔對象模型)把xml文檔轉換成應用程式可以周遊的樹形結構,這樣便可以随機通路其中的節點。它的缺點是需要将整個xml文檔讀入記憶體,消耗記憶體較多。
在qt中使用qdomprocessinginstruction類來表示xml說明,元素對應qdomelement類,屬性對應qdomattr類,文本内容由qdomtext類表示。所有的dom節點,比如這裡的說明、元素、屬性和文本等,都使用qdomnode來表示,然後使用對應的isprocessinginstruction()、iselement()、isattr()和istext()等函數來判斷是否是該類型的元素,如果是,那麼就可以使用toprocessinginstruction()、toelement()、toattr()和totext()等函數轉換為具體的節點類型。
下面來示範一個例子,将讀取前面介紹的xml文檔的内容。
1.建立qt控制台應用,項目名稱為mydom。
2.完成後打開mydom.pro項目檔案,将第一行代碼更改為:
qt += core xml
然後儲存該檔案。
3.打開main.cpp檔案,更改内容如下:
#include <qcoreapplication>
#include <qtxml>
int main(int argc, char *argv[])
{
qcoreapplication a(argc, argv);
// 建立qdomdocument類對象,它代表一個xml文檔
qdomdocument doc;
// 建立指向“my.xml”檔案的qfile對象
qfile file("my.xml");
// 以隻讀方式打開
if (!file.open(qiodevice::readonly)) return 0;
// 将檔案内容讀到doc中
if (!doc.setcontent(&file))
{ file.close(); return 0; }
// 關閉檔案
file.close();
// 獲得doc的第一個節點,即xml說明
qdomnode firstnode = doc.firstchild();
// 輸出xml說明
qdebug() << firstnode.nodename()
<< firstnode.nodevalue();
return a.exec();
}
4.然後先點選一下qt creator左下角的錘子圖示來建構項目,這樣會在源碼目錄旁生成建構目錄,比如這裡是mydom-build-桌面-debug,我們進入該目錄,然後建立一個文本文檔,如下圖所示。
下面将其檔案名更改為my.xml,注意一定要更改擴充名,一些電腦中擴充名可能自動隐藏了,可以去“工具→檔案夾選項→檢視”中修改。提示資訊選擇“是”即可。如下圖所示。
更改完成後使用記事本打開my.xml檔案,然後将前面的xml文檔内容添加進去,儲存退出即可。如下圖所示。
5.現在運作程式,效果如下圖所示。
如果大家不願意看到字元串兩邊的引号,可以将源碼中得qdebug()語句更改如下:
qdebug() << qprintable(firstnode.nodename())
<< qprintable(firstnode.nodevalue());
運作程式,效果如下圖所示。
6.下面在main()函數的return a.exec();一行代碼前繼續添加如下代碼:
qdomelement docelem = doc.documentelement(); //傳回根元素
qdomnode n = docelem.firstchild();
//傳回根節點的第一個子節點
//如果節點不為空
while(!n.isnull())
{
if (n.iselement()) //如果節點是元素
{
qdomelement e = n.toelement(); //将其轉換為元素
qdebug() << qprintable(e.tagname())
//傳回元素标記
<< qprintable(e.attribute("id")); //傳回元素id屬性的值
}
n = n.nextsibling(); //下一個兄弟節點
這裡使用了firstchild()函數和nextsibling()函數,然後利用while()循環來實作對所有子元素的周遊。運作程式,效果如下圖所示。
7.下面更改源碼中得if()語句的内容,輸出所有子節點的内容:
if (n.iselement()) //如果節點是元素
qdomelement e
= n.toelement();
qdebug()
<< qprintable(e.tagname())
<< qprintable(e.attribute("id"));
// 獲得元素e的所有子節點的清單
qdomnodelist list
= e.childnodes();
// 周遊該清單
for(int i=0;
i<list.count(); i++)
{
qdomnode node
= list.at(i);
if(node.iselement())
qdebug()
<< " " << qprintable(node.toelement().tagname())
<<qprintable(node.toelement().text());
這裡使用了childnodes()函數獲得了元素所有子節點的清單,然後通過周遊這個清單實作了周遊其所有子元素。運作程式,效果如下圖所示。
結語
通過上面的例子,我們實作了對一個xml文檔的讀取。可以看到,在qdom中,是将整個xml檔案讀到記憶體中的doc對象中的。然後使用節點(qdomnode )操作doc對象,像xml說明,元素,屬性,文本等等都被看做是節點,這樣就使得操作xml文檔變得很簡單,我們隻需通過轉換函數将節點轉換成相應的類型,如
qdomelement e =n.toelement();
在下一節我們将講述xml檔案的建立和寫入。
涉及到的源碼:
kb, 下載下傳次數: 12)