王超 鄭清
(成都理工大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,四川成都610059)
可擴(kuò)展標(biāo)記語言(Extensible Markup Language,XML),用于標(biāo)記電子文件使其具有結(jié)構(gòu)性的標(biāo)記語言,可以用來標(biāo)記數(shù)據(jù)、定義數(shù)據(jù)類型,是一種允許用戶對自己的標(biāo)記語言進(jìn)行定義的源語言。XML是標(biāo)準(zhǔn)通用標(biāo)記語言(SGML)的子集,非常適合Web傳輸。XML提供統(tǒng)一的方法來描述和交換獨(dú)立于應(yīng)用程序或供應(yīng)商的結(jié)構(gòu)化數(shù)據(jù),是獨(dú)立于軟件和硬件的信息傳輸工具。
XML與HTML的設(shè)計(jì)區(qū)別是:XML是用來存儲數(shù)據(jù)的,重在數(shù)據(jù)本身。而HTML是用來定義數(shù)據(jù)的,重在數(shù)據(jù)的顯示模式。HTML旨在顯示信息,而XML旨在傳輸信息。因此與HTML比起來,XML應(yīng)用起來更方便,用戶可以根據(jù)自己得需要存儲數(shù)據(jù),而無需顧慮格式,XML只要求鍵值對成對出現(xiàn),并按照樹狀結(jié)果存儲即可。XML允許創(chuàng)作者定義自己的標(biāo)簽和自己的文檔結(jié)構(gòu)。
提到用C++解析XML,就不得不提起Tinyxml。Tinyxml是一個(gè)基于DOM模型的、非驗(yàn)證的輕量級C++解釋器。眾所周知,目前XML的解析主要有兩大模型:SAX和DOM。
其中SAX是基于事件的,其基本工作流程是分析XML文檔,當(dāng)發(fā)現(xiàn)了一個(gè)新的元素時(shí),產(chǎn)生一個(gè)對應(yīng)事件,并調(diào)用相應(yīng)的用戶處理函數(shù)。這種方式占用內(nèi)存少,速度快,但用戶程序相應(yīng)會比較復(fù)雜。而DOM(文檔對象模型),則是在分析時(shí),一次性地將整個(gè)XML文檔進(jìn)行分析,并在內(nèi)存中形成對應(yīng)的樹結(jié)構(gòu),同時(shí),向用戶提供一系列的接口來訪問和編輯該樹結(jié)構(gòu)。這種方式占用內(nèi)存大,速度往往慢于SAX,但可以給用戶提供一個(gè)面向?qū)ο蟮脑L問接口,對用戶更為友好。那何為驗(yàn)證和為非驗(yàn)證呢?首先一個(gè)合格的XML文檔必須符合其基本的格式要求。例如第一行要有聲明,標(biāo)簽的嵌套層次必須前后一致等等。解析器也分為兩種,一種是驗(yàn)證的,即會跟據(jù)XML文件中的聲明,用相應(yīng)的DTD文件對XML文件進(jìn)行校驗(yàn),檢查它是否滿足DTD文件的要求;另一種是忽略DTD文件,只要基本格式正確,就可以進(jìn)行解析。Tinyxml是不支持驗(yàn)證的,適合解析比較簡單的XML文件,比如配置文件等。
TinyxML是一個(gè)開源的解析XML的解析庫,所以Tinyxml庫在網(wǎng)上即可下載,做了相應(yīng)的配置之后我們就可以使用它了。首先先介紹一下Tinyxml主要類間的關(guān)系。
TiXm lBase:整個(gè)TinyXML模型的基類。
TiXm lAttribute:對應(yīng)于XML中的元素的屬性。
TiXm lNode:對應(yīng)于DOM結(jié)構(gòu)中的節(jié)點(diǎn)。
TiXm lComment:對應(yīng)于XML中的注釋。
TiXm lDeclaration:對應(yīng)于XML中的申明部分。
TiXm lDocument:對應(yīng)于XML的整個(gè)文檔。
TiXm lElement:對應(yīng)于XML的元素。
TiXm lText:對應(yīng)于XML的文字部分。
TiXm lUnknown:對應(yīng)于XML的未知部分。
TiXm lHandler:定義了針對XML的一些操作。
在使用TinyXm l時(shí)有一點(diǎn)需要我們注意,因?yàn)樗遣恢С烛?yàn)證的,所以當(dāng)我們解析某個(gè)文件的時(shí)候,要檢查返回的指針是否為空,否則會出現(xiàn)內(nèi)存的訪問錯(cuò)誤。
C++的開發(fā)離不開STL(標(biāo)準(zhǔn)模板庫)的使用。STL(標(biāo)準(zhǔn)模板庫)是在惠普實(shí)驗(yàn)室中開發(fā)的,已納入ANSI/ISO C++標(biāo)準(zhǔn)。其中的代碼采用模板類及模板函數(shù)的方式,可以極大地提高編程效率。STL中幾個(gè)關(guān)鍵基本概念是我們必須要知道的。首先是容器:可容納各種數(shù)據(jù)類型的數(shù)據(jù)結(jié)構(gòu)。其次是迭代器:可依次存取容器中元素的東西。還有最重要的算法:用來操作容器中的元素的函數(shù)模板。例如,STL用sort()來對一個(gè)vector中的數(shù)據(jù)進(jìn)行排序,用find()來搜索一個(gè)list中的對象。而容器分為三大類:
(1)順序容器。vector:后部插入/刪除,直接訪問;deque:前/后部插入/刪除,直接訪問;list:雙向鏈表,任意位置插入/刪除。(2)關(guān)聯(lián)容器。set:快速查找,無重復(fù)元素;multiset:快速查找,可有重復(fù)元素;map:一對一映射,無重復(fù)元素,基于關(guān)鍵字查找;multimap:一對一映射,可有重復(fù)元素,基于關(guān)鍵字查找。前兩者合稱為第一類容器。3)容器適配器。stack:LIFO;queue:FIFO;priority_queue:優(yōu)先級高的元素先出。
在使用XML做配置文件的時(shí)候,基于XML的特殊性,我們很容易聯(lián)想到使用關(guān)聯(lián)容器存儲我們解析出來的數(shù)據(jù)。而map無疑是我們最好的選擇。我們將從XML讀出來的配置信息存放在map中。map中存放的是成對的key/value。根據(jù)key對元素進(jìn)行排序,可快速地檢索元素。當(dāng)我們要查詢配置信息的時(shí)候,可以高效地得到我們所需的查詢結(jié)果。本文就是使用map作為存儲容器,結(jié)合Tinyxml的使用,達(dá)到高效的對XML配置文檔的解析。應(yīng)用關(guān)鍵代碼如下:
以上程序可以幫助我們讀取XML文檔中第三級子節(jié)點(diǎn)的信息,我們可以根據(jù)實(shí)際需要增加循環(huán)或者嵌套語句來讀取更深級別的節(jié)點(diǎn)信息。通過以上程序,我們可以看出C++與Tinyxm l相結(jié)合可以幫助我們快速讀取XML文檔中的配置信息,也體現(xiàn)了Tinyxm l最大的特點(diǎn),即能夠快速地靜態(tài)連接到程序里面。但由于Tinyxm是非驗(yàn)證的,所以我們在實(shí)際應(yīng)用中要慎重考慮,避免不必要的檢查工作。
[1] 李普曼(Stanley B.Lippman)等.C++Primer中文版[M].李師賢、蔣愛軍等譯.第4版.北京:人民郵電出版社,2008.
[2] 楊柳青.TinyXml在Linux平臺中的應(yīng)用研[J].機(jī)械工程與自動化,2009(5):41-43.
[3] 孫曉非等編著.XM L基礎(chǔ)教程與實(shí)驗(yàn)指導(dǎo)[M].清華大學(xué)出版社,2008.