前言:
最近在開發的過程中,有個需求是對xml進行格式轉化,從一種格式轉化到另外一種格式.因此,就需要讀取xml進行處理.原本打算寫成工具在linux下運行,不過后來考慮到和系統結合,最后也就使用了前台js轉了.反正都是讀取xml,什么技術轉不都是一樣的么?
不過剛開始還是對要使用的技術做了一定的探究.c++要讀取xml有很多種方式.比較又名的有:
rapidXML(這個是網上介紹的,沒用過)
Xerces-C++ XML Parser:通常來說,讀取XML的方法都是將整個文本進行讀取,然后構建成DOM Tree,之后進行遍歷等操作.這個Parser除了支持構建DOM Tree的方式之外,還支持類似於回調函數的方式進行處理(SAX,SAX2).在讀到相應的節點然后調用函數進行處理.DOM Tree的方式好處是簡單,操作很方便,但是劣勢也是很明顯:需要把整個XML讀進之后才能做處理.如果XML很大,那內存就支撐不住了.SAX,SAX2的作用就在此.其可以支持很大的XML,因為其是相當於事件式的處理方式,不需要構建DOM Tree.不過就是比較麻煩.
TinyXML: 這個就是接下來要介紹的庫了.取名Tiny,意在編寫一個輕量級的處理基本XML的工具.因此,其支持的特性有限.下面列出了其不支持的功能:
TinyXML doesn't parse or use DTDs (Document Type Definitions) or XSLs (eXtensible Stylesheet Language.)
-------------------官方說明文檔
其給出的理由也很明確:
1. 支持這兩個特性使得庫更為龐大
2. 使用更為復雜
3. 學習曲線更曲折
需要使用這些特性的可以考慮上面的xerces-C++ XML Parser.很強大.當然也復雜得多
TinyXml使用:
前言說的已經夠多了,咱們就不廢話了,直接講解tinyXml的使用方法.
安裝:
TinyXml的安裝方法並不復雜,或者說沒有安裝這個步驟.
1. 下載tinyXml ,下載tinyxml_2_6_2.zip
2. 解壓unzip tinyxml_2_6_2.zip.(windows就直接解壓就可以了)
對於有vs的朋友來說,直接打開tinyxml.sln就可以了.對於linux用戶來說,則需要拷貝上面全出來的6個文件.
PS.順帶的,我覺得可以把它的Makefile也拷出來.寫得非常不錯.可以參考參考.
使用:
tinyxml的使用方法很簡單,只需要把拷出來的文件放在自己編寫的目錄下面,引用tinyxml.h,tinystr.h即可.
簡單示例代碼:
1 #include "tinyxml.h" 2 #include "tinystr.h" 3 #include <iostream> 4 5 using namespace std; 6 int main(int argc, char *argv[]) 7 { 8 if(argc != 2) 9 { 10 cout << "usage: "<<argv[0] << " xmlfile" << endl; 11 return 1; 12 } 13 TiXmlDocument doc(argv[1]); 14 bool loadOk = doc.LoadFile(); 15 if (!loadOk) 16 { 17 cout << "could load:" << doc.ErrorDesc() << endl; 18 } 19 TiXmlPrinter printer;//提供的工具類,目的是將xml的數據按格式輸出 20 doc.Accept(&printer); 21 cout << printer.CStr() << endl;//輸出 22 23 TiXmlElement*node = doc.FirstChildElement();//獲取第一個element節點 24 cout << node->Value() << endl;//輸出節點的值 25 string t; 26 node->QueryValueAttribute("type", &t);//獲取節點屬性 27 cout << t << endl; 28 29 doc.FirstChild()->NextSibling()->ToElement()->QueryStringAttribute("type", &t);//獲取第二個子節點的數據 30 cout << "2:" << t << endl; 31 32 //使用遍歷的方式進行處理 33 TiXmlNode* child = NULL; 34 TiXmlElement* element = NULL; 35 TiXmlAttribute *attr = NULL; 36 int ct; 37 while(child = doc.FirstChild()->IterateChildren(child)) 38 { 39 cout << child->ValueStr() << "\t"; 40 ct = child->Type(); 41 cout << ct << "\t"; 42 //根據不同的節點類型做相應處理 43 switch(ct) 44 { 45 case TiXmlNode::TINYXML_TEXT: 46 break; 47 case TiXmlNode::TINYXML_ELEMENT: 48 element = child->ToElement(); 49 attr = element->FirstAttribute(); 50 while(attr) 51 { 52 cout << attr->NameTStr() << "=" << attr->ValueStr() << '\t'; 53 attr = attr->Next(); 54 } 55 break; 56 } 57 } 58 59 return 0; 60 }
編譯命令:
g++ -c tinyxmlparser.cpp -DTIXML_USE_STL g++ -c tinyxmlerror.cpp -DTIXML_USE_STL g++ -c tinystr.cpp -DTIXML_USE_STL g++ -c tinyxml.cpp -DTIXML_USE_STL g++ -c xmltest.cpp -DTIXML_USE_STL g++ -o xmltest xmltest.o tinyxmlparser.o tinyxmlerror.o tinystr.o tinyxml.o
或者大家可以參考那個Makefile改改.
xml文件:
<xml> <tag1 type='1'/> <tag2 type='2'/> </xml>
運行結果:
<xml> <tag1 type="1" /> <tag2 type="2" /> </xml> xml 1: tag1 1 type=1 tag2 1 type=2
沒打回車顯得比較混亂,將就這看看.
詳細解釋:
這部分僅僅是我的理解,可能有錯.有錯的話還請告知我下.
tinyxml按照xml的規定,將所有結點做了區分.我們也可以看到類庫中有:
TiXmlDocument:文檔中的根
TiXmlNode: node為文檔中所有結點的父類型.其可以轉化為其他的結點類型.
TiXmlElement: element結點.即我們平常所使用的,具有屬性,tagName的結點.
TiXmlComment: 注釋
TiXmlText: 文字結點.
TiXmlDeclaration: xml的聲明(?xml version="1.0" standalone="yes"?>)
TiXmlUnknown: 任何tinyXml不認的結點都將歸結為unknown,在重新寫回文件時,按照原樣輸出.
一般我們的操作僅僅在於,取tagName,獲取屬性,獲取文字,迭代.這里就講下這些操作.
tagName: 對於element來說,可以使用element->Value()或者element->ValueStr();//兩者區別僅僅在於返回值不同,后者返回string.
對於Value()函數來說,文檔上也解釋了,對於不同的結點,返回值不同.
Document: filename of the xml file Element: name of the element Comment: the comment text Unknown: the tag contents Text: the text string
獲取屬性:獲取屬性有多種方式.最簡單的是采用const char* Attrubute(const char *),或者采用QueryValueAttribute (const std::string &name, T *outValue) const.還有獲取相應類型,如Int,double等的函數.可以自己查看手冊.有時候需要遍歷屬性時,可以這么寫
TiXmlAttribute *attr = NULL; attr = element->FirstAttribute(); while(attr) { cout << attr->NameTStr() << "=" << attr->ValueStr(); attr = attr->Next(); }
獲取文字:element->GetText();
迭代:
TiXmlNode *child = NULL; while(child = parent->IterateChildren(child)) { cout << child->ValueStr() << endl; }
總結:
對於TinyXml的介紹大致到這.還有很多細節還沒敘述,不過可以看看文檔,下的源碼包里頭就有doc,很方便,講的也很詳細.
有什么問題可以隨時討論.歡迎留言哈.