tinyxml2是什麼?
tinyXML2是一個開源的解析XML的C++庫,用於c++項目裏面解析xml文件使用。
下載地址:
https://github.com/leethomason/tinyxml2 ,使用git直接將源碼下載下來。
使用方法:
將下載的源碼包裏面的tinyxml2.h,tinyxml2.cpp拷貝到自己的項目, 使用時包含頭文件,並且
使用編譯指令:using namespace tinyxml2 ,編譯的時候記得加上tinyxml2.cpp,
使用:
#include"tinyxml2.h"
using namespace tinyxml2;
編譯:g++ main.cpp tinyxml2.cpp -o a.out
tinyxml2常用類介紹:
結構圖:
XMLNode所有DOM模型節點類的父類,基本節點類;
XMLDocument:文檔類,它表示整個xml文件對象;
XMLElement:元素類,它是文件的主要部分,支持嵌套,可以包含屬性類和文本類等,是使用最多的類。
XMLText:文本元素類,如:<name>i am student</name>,name節點的i am student就是文本元素。
XMLAttribute:元素屬性類,節點的所有屬性。不是XMLNode的子類;
XMLDeclaration:聲明類,xml文件第一行的內容,聲明xml版本,和所用的編碼集,很少用到,
如: <?xml version="1.0" standalone="yes"?>
XMLComment:註釋節點類,註釋部分,一般都不會使用這個類。
XMLUnknown:未識別的節點類
用的最多的就是紅色標記的2個類。
XMLElement常用方法:
下面四個都可以帶參數來限制查找,不帶參數默認第一個;
XMLElement* FirstChildElement( const char* name = 0):獲取第一子節點,此節點裏麪包含的第一個節點
XMLElement* LastChildElement( const char* name = 0):獲取最後一個節點
XMLElement* NextSiblingElement( const char* name = 0):獲取下一個兄弟節點,同級別的節點
XMLElement*PreviousSiblingElement( const char* name = 0):獲取上一個兄弟節點
const XMLAttribute* FirstAttribute(void):獲取節點的第一個屬性,返回的是const類型的。
char *Attribute( const char* name, const char* value=0 ):根據屬性名稱,獲取屬性值,返回char*類型的屬性值
XMLNode*Parent(void):獲取父節點返回的是XMLNode*類型的,可以轉換對應的類型xxx.Parent()->ToElement()->Name();
const char* GetText():獲取文本元素
XMLAttribute類常用方法:
const char* Name();獲取屬性名稱
const char* Value();獲取屬性值
const XMLAttribute* Next();獲取下一個屬性
其實掌握了上面常用的方法,使用tinyxml2就很簡單了。
#include<stdio.h>
#include<string>
#include<iostream>
#include "tinyxml2.h" //引用頭文件
using namespace std;
using namespace tinyxml2; //使用名稱空間
void show_all_node(XMLElement *tmpnode)
{
while(tmpnode)
{
cout<<"<"<<tmpnode->Name()<<">";
//獲取節點屬性第一個
const XMLAttribute* tmp_attr = tmpnode->FirstAttribute();
//遍歷整個屬性列表
while(tmp_attr)
{
cout<<"attr="<<tmp_attr->Name()<<":"<<tmp_attr->Value()<<",";
//獲取下一個屬性節點
tmp_attr=tmp_attr->Next();
}
if(tmpnode->GetText())//一定要判斷不然會有問題,如果文本爲空的話,會打印text=後直接結束進程
cout<<" text="<<tmpnode->GetText()<<";"<<endl;
show_all_node(tmpnode->FirstChildElement());//遞歸掉用,打印子節點所有屬性和文本信息
//獲取同級別的下一個兄弟元素
tmpnode=tmpnode->NextSiblingElement();
}
}
int main()
{
XMLDocument doc;
doc.LoadFile("./dream.xml");//第一步加載文檔
XMLElement*root=doc.RootElement();//獲取根元素,通過XMLDocument來獲取
cout<<root->Name()<<endl;
XMLDeclaration *decl;//獲取聲明不能直接doc->ToDeclaration();
//不能使用doc.FirstChildElement()->ToDeclaration();
decl=doc.FirstChild()->ToDeclaration();
if(decl!=NULL)
{
cout<< decl->Value()<<endl;
}
//show_all_node(root);//遍歷root節點下的所有節點
//獲取第一個節點
XMLElement*tmpnode=root->FirstChildElement();
cout<<tmpnode->Name()<<endl;//打印名稱
tmpnode=tmpnode->LastChildElement("LINE");//獲取最後一個名稱爲LINE的元素
cout<<tmpnode->Name()<<endl;//打印名稱
tmpnode=tmpnode->PreviousSiblingElement("SPEAKER");//獲取前一個名稱爲SPEAKER的元素
//獲取元素文檔內容
if(tmpnode->GetText())//這裏要加個判斷,不加如果爲空的化,下面打印會出問題,目前不知到原因。
{
cout<<tmpnode->GetText()<<endl;
}
const XMLAttribute*attr=tmpnode->FirstAttribute();//獲取元素第一個屬性節點,注意返回的是const類型的
cout<<attr->Name()<<":"<<attr->Value()<<endl;//打印屬性名稱和值
const XMLAttribute*attr2=attr->Next();//獲取下一個屬性
cout<<attr->Name()<<":"<<attr->Value()<<endl;//打印屬性名稱和值
cout<<tmpnode->Attribute("name")<<endl;//直接獲取name元素屬性值
// doc.Print();//打印整個文檔內容
return 0;
}
dream.xml文件內容,
<?xml version="1.0"?>
<!-- 註釋節點-->
<PLAY>
<SPEECH>
<SPEAKER id="1" name="speakattr">text node</SPEAKER>
<LINE>What, dead, my dove?</LINE>
<LINE>Speak, speak. Quite dumb?</LINE>
</SPEECH>
<SPEECH2>
<SPEAKER id="2" name="speaker2">PUCK</SPEAKER>
<LINE>So, good night unto you all.</LINE>
</SPEECH2>
</PLAY>
liunx環境編譯:g++ main.cpp tinyxml2.cpp -o tinytest
./tinytest
PLAY
xml version="1.0"
SPEECH
LINE
text node
id:1
id:1
speakattr
可以去掉遍歷節點函數註釋:show_all_node(root);
函數打印如下:
./tinytest
PLAY
xml version="1.0"
<PLAY><SPEECH><SPEAKER>attr=id:1,attr=name:speakattr, text=text node;
<LINE> text=What, dead, my dove?;
<LINE> text=Speak, speak. Quite dumb?;
<SPEECH2><SPEAKER>attr=id:2,attr=name:speaker2, text=PUCK;
<LINE> text=So, good night unto you all.;
SPEECH
LINE
text node
id:1
id:1
speakatt