TinyXml 操作XML 常用操作(zhuan)
源代碼下載下傳:http://sourceforge.net/projects/tinyxml/files/
如下是一個XML片段:
<Persons>
<Person ID="1">
<name>周星星</name>
<age>20</age>
</Person>
<Person ID="2">
<name>白晶晶</name>
<age>18</age>
</Person>
</Persons>
在TinyXML中,根據XML的各種元素來定義了一些類:
TiXmlBase:整個TinyXML模型的基類。
TiXmlAttribute:對應于XML中的元素的屬性。
TiXmlNode:對應于DOM結構中的節點。
TiXmlComment:對應于XML中的注釋。
TiXmlDeclaration:對應于XML中的申明部分,即<?versiong="1.0" ?>。
TiXmlDocument:對應于XML的整個文檔。
TiXmlElement:對應于XML的元素。
TiXmlText:對應于XML的文字部分。
TiXmlUnknown:對應于XML的未知部分。
TiXmlHandler:定義了針對XML的一些操作。
那我們如何使用這些類以及他們的方法來操縱我們的XML呢?請看下面。
一、讀取XML(假設我們的Xml文檔中的内容與上面的Xml内容一樣)
// 建立一個XML的文檔對象。
TiXmlDocument *myDocument = new TiXmlDocument("填上你的Xml檔案名");
myDocument->LoadFile();
// 獲得根元素,即Persons。
TiXmlElement *RootElement = myDocument.RootElement();
// 輸出根元素名稱,即輸出Persons。
cout << RootElement->Value() << endl;
// 獲得第一個Person節點。
TiXmlElement *FirstPerson = RootElement->FirstChildElement();
// 獲得第一個Person的name節點和age節點和ID屬性。
TiXmlElement *NameElement = FirstPerson->FirstChildElement();
TiXmlElement *AgeElement = NameElement->NextSiblingElement();
TiXmlAttribute *IDAttribute = FirstPerson->FirstAttribute();
// 輸出第一個Person的name内容,即周星星;age内容,即20;ID屬性,即1。
cout << NameElement->FirstChild()->Value << endl;
cout << AgeElement->FirstChild()->Value << endl;
cout << IDAttribute->Value() << endl;
看,讀取XML是不是很簡單阿,和Java的XML解析庫非常的相似,就是名字改了一下而已。
二、生成XML内容
// 建立一個XML的文檔對象。
TiXmlDocument *myDocument = new TiXmlDocument();
// 建立一個根元素并連接配接。
TiXmlElement *RootElement = new TiXmlElement("Persons");
myDocument->LinkEndChild(RootElement);
// 建立一個Person元素并連接配接。
TiXmlElement *PersonElement = new TiXmlElement("Person");
RootElement->LinkEndChild(PersonElement);
// 設定Person元素的屬性。
PersonElement->SetAttribute("ID", "1");
// 建立name元素、age元素并連接配接。
TiXmlElement *NameElement = new TiXmlElement("name");
TiXmlElement *AgeElement = new TiXmlElement("age");
PersonElement->LinkEndChild(NameElement);
PersonElement->LinkEndChild(AgeElement);
// 設定name元素和age元素的内容并連接配接。
TiXmlText *NameContent = new TiXmlText("周星星");
TiXmlText *AgeContent = new TiXmlText("20");
NameElement->LinkEndChild(NameContent);
AgeElement->LinkEndChild(AgeContent);
// 儲存到檔案
myDocument->SaveFile("要儲存的xml檔案名");
這樣,便建立了一個如下的xml檔案:
<Persons>
<Person ID="1">
<name>周星星</name>
<age>20</age>
</Person>
</Persons>
TinyXML入門教程
TinyXML入門教程 1
什麼是XML? 1
文檔類 2
建立文檔對象 3
輸出文檔對象 3
儲存文檔對象 4
傳回第一個根元素 5
聲明類 5
注釋類 6
元素類 6
節點名 6
父節點 6
子節點 7
編輯子節點 7
同級節點 7
周遊元素 8
元素屬性 8
元素函數總結 9
屬性類 10
什麼是XML?
XML全稱EXtensible Markup Language,翻譯為可擴充标記語言,簡而言之就是你可以自定義資料的辨別,以此來區分各種不同的資料,以便于進行資料交換,例如html就可以了解為一種簡單的xml語言。XML檔案通常就是一個文本檔案,可以使用任何編碼
上圖就是我系統中一個xml檔案的圖示,使用VC2005打開它,你可以看到如下内容:
XML也是有這幾個對象組成了,一般來說我們經常使用的類如下:
l TiXmlDocument:文檔類,它代表了整個xml檔案。
l TiXmlDeclaration:聲明類,它表示檔案的聲明部分,如上圖所示。
l TiXmlComment:注釋類,它表示檔案的注釋部分,如上圖所示。
l TiXmlElement:元素類,它是檔案的主要部分,并且支援嵌套結構,一般使用這種結構來分類的存儲資訊,它可以包含屬性類和文本類,如上圖所示。
n TiXmlAttribute/TiXmlAttributeSet:元素屬性,它一般嵌套在元素中,用于記錄此元素的一些屬性,如上圖所示。
n TiXmlText:文本對象,它嵌套在某個元素内部,如上圖所示。
TinyXml使用文檔對象模型(DOM)來解析xml檔案,這種模型的處理方式為在分析時,一次性的将整個XML文檔進行分析,并在記憶體中形成對應的樹結構,同時,向使用者提供一系列的接口來通路和編輯該樹結構。這種方式占用記憶體大,但可以給使用者提供一個面向對象的通路接口,對使用者更為友好,非常友善使用者使用。下面我們依次來介紹各個類的用法。
文檔類
文檔類代表一個XML文檔,通過它,你可以儲存,載入和列印輸出文檔。你可以通過以下方式載入xml文檔到TiXmlDocument。
建立文檔對象
l 建立一個空的文檔對象,然後載入一個xml文檔
使用到的函數原形如下:
+TiXmlDocument();
+ bool LoadFile( const std:: string & filename)
在程式中你可以如下使用:
// 載入xml文檔
TiXmlDocument doc();
doc.LoadFile("tutorial.xml");
l 2、在構造函數中傳入文檔的名稱,然後調用load函數完成解析載入
使用到的函數原形如下:
+TiXmlDocument( const std:: string & documentName );
+ bool LoadFile();
在程式中你可以如下使用:
// 載入xml文檔
TiXmlDocument doc("tutorial.xml");
doc.LoadFile();
輸出文檔對象
文檔類提供了Print()函數用于在控制台輸出目前的文檔内容,這個函數的原形如下:
+ void Print() const
在程式中你可以如下使用:
// 載入xml文檔
TiXmlDocument doc("tutorial.xml");
doc.LoadFile();
doc.Print(); // 輸出文檔
tutorial.xml的内容如下:
<?xml version="1.0" standalone="yes" encoding="utf-8"?>
<!--comment 注釋-->
<element attribute="this a attribute(這是一個屬性)" int = "1" float = "3.14">
<subelement1>
This a text(這是一個文本)
</subelement1>
<subelement2/>
<subelement3/>
<subelement4/>
</element>
在控制台中你可以得到如下輸出:
由于檔案使用UTF-8編碼,而Windows下的控制台預設使用gb2312編碼,是以會生成亂碼。
儲存文檔對象
當然你也可以使用SaveFile()函數來進行另存為,這個函數的原形如下:
bool SaveFile( const std:: string & filename ) const
在程式中你可以如下使用:
// 載入xml文檔
TiXmlDocument doc("tutorial.xml");
doc.LoadFile();
doc.Print(); // 輸出文檔
cout<<endl;
doc.SaveFile("tutorial.txt");
使用記事本打開tutorial.txt,你可以看到如下内容。
傳回第一個根元素
另外文檔對象還提供了一個實用的函數用于傳回第一個根對象,它可以讓你友善的周遊整個文檔結構,查找自己需要的資料。函數原形如下:
+TiXmlElement* RootElement()
我們在介紹元素類的時候再詳細介紹它的使用。
聲明類
在标準的XML檔案中,聲明為檔案的第一項,例如<?xml version="1.0" standalone="yes"?>,聲明對象具有三個屬性值,版本,編碼和獨立檔案聲明
一般來說文檔的第一行就是聲明對象,你可以把文檔對象的第一個子節點轉換為聲明對象。
// 使用TinyXml的聲明對象
TiXmlDeclaration *decl;
decl = doc.FirstChild()->ToDeclaration();
然後就可以使用它的功能了,它可以讓你傳回目前的版本,編碼等資訊,函數原形如下:
+ const char *Version() const
+ const char *Encoding() const
+ const char *Standalone() const
在程式中你可以如下使用:
// 使用TinyXml的聲明對象
TiXmlDeclaration *decl;
decl = doc.FirstChild()->ToDeclaration();
cout<<"使用TinyXml的聲明對象(TiXmlDeclaration)"<<endl;
// 輸出聲明對象對應的xml内容
decl->Print(0,4,&str);
cout<<str<<endl;
// 分别輸出聲明對象的屬性
cout<<"版本:"<<decl->Version()<<" 是否為對立檔案:"<<decl->Standalone()<<" 編碼方式:"<<decl->Encoding()<<endl;
cout<<endl;
注釋類
這個類一般為xml資料提供解釋說明,在程式中一般不使用它,是以,這裡就不介紹了。
元素類
元素為一個容器類,它具有元素名稱,并可以包含其它元素,文本,注釋和未知節點,這些對象統稱為元素的節點,即節點可以為元素、文本、注釋和未知節點類型。元素也可以包含任意個數的屬性。
我們還是以如下的XML代碼來說明這個類的功能。
<element attribute="this a attribute(這是一個屬性)" int = "1" float = "3.14">
<subelement1>
This a text(這是一個文本)
</subelement1>
<subelement2/>
<subelement3/>
<subelement4/>
</element>
節點名
在上方元素的代碼中,element為根元素的名稱,你可以通過如下的函數來設定和傳回它。
+ const std:: string & ValueStr() const
+ void SetValue( const std:: string & _value )
父節點
subelement1,subelement2,subelement3,subelement4都是element的子元素,如果目前元素對象的指針指向subelement1,subelement2,subelement3,subelement4,你可以通過Parent()函數來傳回指向element對象的指針,Parent()函數的聲明如下:
+TiXmlNode* Parent()
子節點
通過父節點的指針,你可以周遊所有的子節點。
+TiXmlNode* FirstChild()
+TiXmlNode* FirstChild( const std:: string & _value )
上面兩個函數用于傳回第一個子節點對象的指針,帶參數名的那個函數表示傳回第一個名為_value的子節點。
+TiXmlNode* LastChild()
+TiXmlNode* LastChild( const std:: string & _value )
上面的兩個函數用于傳回最後一個節點對象的指針,帶參數名的那個函數表示傳回最後一個名為_value的子節點。
你也可以使用IterateChildren()函數來依次周遊所有的節點,它們的函數聲明如下:
+TiXmlNode* IterateChildren( const TiXmlNode* previous )
+TiXmlNode* IterateChildren( const std:: string & _value, const TiXmlNode* previous )
帶參數名的那個函數表示隻周遊同名的節點。
編輯子節點
你可以插入、删除替換所有的子節點。
+TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
上面三個函數用于插入節點,InsertEndChild函數讓你把新節點插入到末尾,InsertBeforeChild和InsertAfterChild函數允許你在指定的節點位置前後插入節點。
+TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
ReplaceChild函數用于替換指定的節點。
+ bool RemoveChild( TiXmlNode* removeThis );
RemoveChild函數讓你删除指定的節點。
void Clear();
Clear函數會删除本節點的所有子節點(包括子節點包含的從子節點),但不會修改本節點。
同級節點
<element attribute="this a attribute(這是一個屬性)" int = "1" float = "3.14">
<subelement1>
This a text(這是一個文本)
</subelement1>
<subelement2/>
<subelement3/>
<subelement4/>
</element>
在上面的xml代碼中,subelement1、subelement2、subelement3、subelement4都屬于同級節點,我們也提供了相關的函數用于在這些同級節點中周遊。
+TiXmlNode* PreviousSibling()
+TiXmlNode* PreviousSibling( const std:: string & _value )
可以根據目前的節點,傳回上一個節點的指針。帶參數名的那個函數表示傳回上一個名為_value的節點。
當然你也可以根據目前的節點,傳回下一個節點的指針。帶參數名的那個函數表示傳回下一個名為_value的節點。
+TiXmlNode* NextSibling()
+TiXmlNode* NextSibling( const std:: string & _value)
周遊元素
元素是一種特殊的節點,以’<’為開始字元,後接元素名稱。函數NextSiblingElement用于傳回下一個同級元素,而忽略其它類型的節點。它們的函數聲明如下:
+TiXmlElement* NextSiblingElement()
+TiXmlElement* NextSiblingElement( const std:: string & _value)
帶參數名的那個函數表示傳回下一個名為_value的同級元素。
本類也提供了相關的函數,讓你傳回第一個子元素。
+TiXmlElement* FirstChildElement()
+TiXmlElement* FirstChildElement( const std:: string & _value )
帶參數名的那個函數表示傳回下一個名為_value的子元素。
元素屬性
屬性一般儲存在元素中,它們為使用“=”号連接配接的兩個字元串,左邊的表示屬性名,等号右邊的表示屬性值,通常使用字元串、整數和浮點數等資料類型表示。例如,pi = 3.14。
你可以通過如下的函數,傳回屬性值。
+ const std:: string * Attribute( const std:: string & name ) const ;
+ const std:: string * Attribute( const std:: string & name, int * i ) const ;
+ const std:: string * Attribute( const std:: string & name, double * d ) const ;
在上面3個函數中,第一個函數使用字元串儲存傳回的屬性值,第二個函數把屬性值轉換為整數然後傳回,第三個函數把屬性值轉換為浮點數然後傳回。不過,第二、三個函數都會以字元串的形式記錄屬性值,并作為函數的傳回值傳回。
另外,你也可以使用模闆函數:
+template< typename T > int QueryValueAttribute( const std:: string & name, T* outValue ) const
來傳回特點的屬性值,它會根據你傳入的參數,自動選擇合适資料類型。
另外,本類也提供了如下三個函數讓你設定屬性,參數的類型和傳回函數類似。
+ void SetAttribute( const std:: string & name, const std:: string & _value );
+ void SetAttribute( const std:: string & name, int _value );
+ void SetDoubleAttribute( const char * name, double value );
FirstAttribute和LastAttribute可以讓你傳回第一個和最後一個屬性,它們的函數聲明如下:
+TiXmlAttribute* FirstAttribute()
+TiXmlAttribute* LastAttribute()
RemoveAttribute函數可以讓你删除指定名稱的屬性,它的函數聲明如下:
+ void RemoveAttribute( const std:: string & name )
元素函數總結
ValueStr // 傳回元素名稱
SetValue // 設定元素名稱
Parent // 傳回父節點對象
FirstChild // 傳回第一個子節點
LastChild // 傳回最後一個子節點
IterateChildren // 傳回下一個子節點
InsertEndChild // 在最後一個子節點後插入子節點
InsertBeforeChild // 在指定的子節點前插入子節點
InsertAfterChild // 在指定的子節點後插入子節點
ReplaceChild // 替換指定的子節點
RemoveChild // 删除指定的子節點
Clear // 删除所有的子節點
PreviousSibling // 傳回同級中前一個節點
NextSibling // 傳回同級中後一個節點
NextSiblingElement // 傳回同級中後一個元素
FirstChildElement // 傳回第一個子元素節點
Attribute // 傳回元素中的屬性值
QueryValueAttribute // 傳回元素中的屬性值
SetAttribute // 設定元素中的屬性值
FirstAttribute // 傳回元素中第一個屬性對象
LastAttribute // 傳回元素中最後一個屬性對象
RemoveAttribute // 删除元素中指定的屬性對象
屬性類
屬性為名稱="值"對,元素可以具有屬性值,但名稱必須唯一。
你可以通過
+ const std:: string & NameTStr() const
傳回屬性名稱
也可以通過下面三個函數傳回屬性值:
+ const std:: string & ValueStr() const
+ int IntValue() const ;
+ double DoubleValue() const ;
當然你也可以設定屬性值,它們的函數聲明如下:
+ void SetName( const std:: string & _name )
+ void SetIntValue( int _value );
+ void SetDoubleValue( double _value );
+ void SetValue( const std:: string & _value )
以上函數與元素類中的相關函數類似,這裡不重複介紹了。
在元素屬性中,通常具有許多屬性,你可以通過Next函數傳回下一個屬性對象的指針,也可以通過Previous函數獲得上一個屬性對象的指針。它們的函數聲明如下:
+TiXmlAttribute* Next()
+TiXmlAttribute* Previous()