[Qt教程] 第27篇 XML(一)使用DOM读取XML文档
生活随笔
收集整理的這篇文章主要介紹了
[Qt教程] 第27篇 XML(一)使用DOM读取XML文档
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
[Qt教程]?第27篇 XML(一)使用DOM讀取XML文檔
??|?查看: 1001|?回復(fù): 14| 使用DOM讀取XML文檔 版權(quán)聲明 該文章原創(chuàng)于作者yafeilinux,轉(zhuǎn)載請注明出處! 導(dǎo)語 XML(ExtensibleMarkup Language,可擴(kuò)展標(biāo)記語言),是一種類似于HTML的標(biāo)記語言,但它的設(shè)計(jì)目的是用來傳輸數(shù)據(jù),而不是顯示數(shù)據(jù)。XML的標(biāo)簽沒有被預(yù)定義,用戶需要在使用時(shí)自行進(jìn)行定義。XML是W3C(萬維網(wǎng)聯(lián)盟)的推薦標(biāo)準(zhǔn)。相對于數(shù)據(jù)庫表格的二維表示,XML使用的樹形結(jié)構(gòu)更能表現(xiàn)出數(shù)據(jù)的包含關(guān)系,作為一種文本文件格式,XML簡單明了的特性使得它在信息存儲(chǔ)和描述領(lǐng)域非常流行。 ? ?? ??在Qt中提供了QtXml模塊來進(jìn)行XML文檔的處理,我們在Qt幫助中輸入關(guān)鍵字QtXml Module,可以看到該模塊的類表。這里主要提供了三種解析方法:?DOM方法,可以進(jìn)行讀寫;SAX方法,可以進(jìn)行讀取;基于流的方法,分別使用QXmlStreamReader和QXmlStreamWriter進(jìn)行讀取和寫入。要在項(xiàng)目中使用QtXml模塊,還需要在項(xiàng)目文件(.pro文件)中添加QT += xml一行代碼。這一節(jié)我們先來講解一下DOM的方法。 環(huán)境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2 目錄 一、XML文檔示例 二、使用DOM讀取XML文檔內(nèi)容 正文 一、XML文檔示例 下面是一個(gè)規(guī)范的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> 每個(gè)XML文檔都由XML說明(或者稱為XML序言)開始,它是對XML文檔處理的環(huán)境和要求的說明,比如這里的<?xmlversion="1.0" encoding="UTF-8"?>,其中xml version=“1.0”,表明使用的XML版本號,這里字母是區(qū)分大小寫的;encoding=“UTF-8”是使用的編碼,指出文檔是使用何種字符集建立的,默認(rèn)值為Unicode編碼。XML文檔內(nèi)容由多個(gè)元素組成,一個(gè)元素由起始標(biāo)簽<標(biāo)簽名>和終止標(biāo)簽</標(biāo)簽名>以及兩個(gè)標(biāo)簽之間的內(nèi)容組成,而文檔中第一個(gè)元素被稱為根元素,比如這里的<library></library>,XML文檔必須有且只有一個(gè)根元素。元素的名稱是區(qū)分大小寫的,元素還可以嵌套,比如這里的library、book、title和author等都是元素。元素可以包含屬性,用來描述元素的相關(guān)信息,屬性名和屬性值在元素的起始標(biāo)簽中給出,格式為<元素名?屬性名=“屬性值”>,如<book id=“01”>,屬性值必須在單引號或者雙引號中。在元素中可以包含子元素,也可以只包含文本內(nèi)容,比如這里的<title>Qt</title>中的Qt就是文本內(nèi)容。 二、使用DOM讀取XML文檔內(nèi)容 Dom(Document Object Model,即文檔對象模型)把XML文檔轉(zhuǎn)換成應(yīng)用程序可以遍歷的樹形結(jié)構(gòu),這樣便可以隨機(jī)訪問其中的節(jié)點(diǎn)。它的缺點(diǎn)是需要將整個(gè)XML文檔讀入內(nèi)存,消耗內(nèi)存較多。 在Qt中使用QDomProcessingInstruction類來表示XML說明,元素對應(yīng)QDomElement類,屬性對應(yīng)QDomAttr類,文本內(nèi)容由QDomText類表示。所有的DOM節(jié)點(diǎn),比如這里的說明、元素、屬性和文本等,都使用QDomNode來表示,然后使用對應(yīng)的isProcessingInstruction()、isElement()、isAttr()和isText()等函數(shù)來判斷是否是該類型的元素,如果是,那么就可以使用toProcessingInstruction()、toElement()、toAttr()和toText()等函數(shù)轉(zhuǎn)換為具體的節(jié)點(diǎn)類型。 下面來演示一個(gè)例子,將讀取前面介紹的XML文檔的內(nèi)容。 1.新建Qt控制臺(tái)應(yīng)用,項(xiàng)目名稱為myDom。 2.完成后打開myDom.pro項(xiàng)目文件,將第一行代碼更改為: QT? ?? ??+= core? ? xml 然后保存該文件。 3.打開main.cpp文件,更改內(nèi)容如下: #include?<QCoreApplication> #include?<QtXml> int?main(int?argc,?char?*argv[]) {? ?? ? ? QCoreApplication?a(argc,?argv);?? ?? ? ? //?新建QDomDocument類對象,它代表一個(gè)XML文檔? ?? ? ? QDomDocument?doc;? ?? ? ? //?建立指向“my.xml”文件的QFile對象? ?? ? ? QFile?file("my.xml");? ? ? ???//?以只讀方式打開? ? ? ???if?(!file.open(QIODevice::ReadOnly))?return?0;? ? ? ???//?將文件內(nèi)容讀到doc中? ? ? ???if?(!doc.setContent(&file))? ? ? {?file.close();?return?0;?}? ? ? ???//?關(guān)閉文件? ?? ? ? file.close();? ?? ? ? //?獲得doc的第一個(gè)節(jié)點(diǎn),即XML說明? ? ? ???QDomNode?firstNode?=?doc.firstChild();? ?? ? ???//?輸出XML說明? ?? ? ???qDebug()?<<?firstNode.nodeName()? ??<<?firstNode.nodeValue();?? ?? ? ???return?a.exec(); } 4.然后先點(diǎn)擊一下Qt Creator左下角的錘子圖標(biāo)來構(gòu)建項(xiàng)目,這樣會(huì)在源碼目錄旁生成構(gòu)建目錄,比如這里是myDom-build-桌面-Debug,我們進(jìn)入該目錄,然后新建一個(gè)文本文檔,如下圖所示。 下面將其文件名更改為my.xml,注意一定要更改擴(kuò)展名,一些電腦中擴(kuò)展名可能自動(dòng)隱藏了,可以去“工具→文件夾選項(xiàng)→查看”中修改。提示信息選擇“是”即可。如下圖所示。 更改完成后使用記事本打開my.xml文件,然后將前面的xml文檔內(nèi)容添加進(jìn)去,保存退出即可。如下圖所示。 5.現(xiàn)在運(yùn)行程序,效果如下圖所示。 如果大家不愿意看到字符串兩邊的引號,可以將源碼中得qDebug()語句更改如下: qDebug()?<<?qPrintable(firstNode.nodeName()) ? ?? ?? ?? ??<<?qPrintable(firstNode.nodeValue()); 運(yùn)行程序,效果如下圖所示。 6.下面在main()函數(shù)的return?a.exec();一行代碼前繼續(xù)添加如下代碼: QDomElement?docElem?=?doc.documentElement();??//返回根元素 QDomNode?n?=?docElem.firstChild();? ?//返回根節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn) //如果節(jié)點(diǎn)不為空 while(!n.isNull()) { ? ?if?(n.isElement())??//如果節(jié)點(diǎn)是元素 ? ?{ ? ?? ?QDomElement?e?=?n.toElement();??//將其轉(zhuǎn)換為元素 ? ?? ?qDebug()?<<?qPrintable(e.tagName())? ?//返回元素標(biāo)記 ? ?? ?? ?<<?qPrintable(e.attribute("id"));??//返回元素id屬性的值 ? ??} ? ?? ?n?=?n.nextSibling();??//下一個(gè)兄弟節(jié)點(diǎn) } 這里使用了firstChild()函數(shù)和nextSibling()函數(shù),然后利用while()循環(huán)來實(shí)現(xiàn)對所有子元素的遍歷。運(yùn)行程序,效果如下圖所示。 7.下面更改源碼中得if()語句的內(nèi)容,輸出所有子節(jié)點(diǎn)的內(nèi)容: if?(n.isElement())??//如果節(jié)點(diǎn)是元素 { ? ??QDomElement?e = n.toElement(); ? ??qDebug() << qPrintable(e.tagName()) ? ?? ?? ?? ?<<?qPrintable(e.attribute("id")); ? ??//?獲得元素e的所有子節(jié)點(diǎn)的列表 ? ??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()函數(shù)獲得了元素所有子節(jié)點(diǎn)的列表,然后通過遍歷這個(gè)列表實(shí)現(xiàn)了遍歷其所有子元素。運(yùn)行程序,效果如下圖所示。 結(jié)語 通過上面的例子,我們實(shí)現(xiàn)了對一個(gè)XML文檔的讀取。可以看到,在QDom中,是將整個(gè)XML文件讀到內(nèi)存中的doc對象中的。然后使用節(jié)點(diǎn)(QDomNode )操作doc對象,像XML說明,元素,屬性,文本等等都被看做是節(jié)點(diǎn),這樣就使得操作XML文檔變得很簡單,我們只需通過轉(zhuǎn)換函數(shù)將節(jié)點(diǎn)轉(zhuǎn)換成相應(yīng)的類型,如 QDomElement e =n.toElement(); 在下一節(jié)我們將講述XML文件的創(chuàng)建和寫入。 涉及到的源碼:??myDom.zip?? |
總結(jié)
以上是生活随笔為你收集整理的[Qt教程] 第27篇 XML(一)使用DOM读取XML文档的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Qt教程] 第29篇 XML(三)Qt
- 下一篇: [Qt教程] 第26篇 数据库(六)SQ