TinyXML是一個開源的解析XML的解析庫,能夠用於C++,能夠在Windows或Linux中編譯。這個解析庫的模型通過解析XML文件,然後在內存中生成DOM模型,從而讓我們很方便的遍歷這棵XML樹。tinyXML資源包見本人上傳的資源,需要可下載!
下面我用個簡單的例子說明如何使用tinyXML操作xml文件。在講例子之前我先說說tinyXML中主要類和xml文檔之間的對應關係。下面是tinyXML中主要class的類圖,反應各個類之間的靜態關係。
TiXmlBase是所有類的基類,TiXmlNode、TiXmlAttribute兩個類都繼承來自TiXmlBase類,其中TiXmlNode類指的是所有被<...>...<.../>包括的內容,而xml中的節點又具體分爲以下幾方面內容,分別是聲明、註釋、節點以及節點間的文本,因此在TiXmlNode的基礎上又衍生出這幾個類TiXmlComment、TiXmlDeclaration、TiXmlDocument、TiXmlElement、TiXmlText、TiXmlUnknown,分別用來指明具體是xml中的哪一部分。TiXmlAttribute類不同於TiXmlNode,它指的是在尖括號裏面的內容,像<...
***=...>,其中***就是一個屬性。這塊我具體用一個xml文檔說明一下,內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<phonebook>
<!--one item behalfs one contacted person.-->
<item>
<name>miaomaio</name>
<addr>Shaanxi Xi'an</addr>
<tel>13759911917</tel>
<email>[email protected]</email>
</item>
<item>
<name>gougou</name>
<addr>Liaoning Shenyang</addr>
<tel>15840330481</tel>
<email>[email protected]</email>
</item>
<!--more contacted persons.-->
</phonebook>
*像TiXmlDeclaration指的就是<?xml version="1.0" encoding="UTF-8"?>,
*像TiXmlComment指的就是<!--one item behalfs one contacted person.-->、 <!--more contacted person s.-->,
*像TiXmlDocument指的就是整個xml文檔,
*像TiXmlElement指的就是<phonebook>、<item>、<name>、<addr>等等這些節點,
*像TiXmlText指的就是‘gougou’、‘15840330481’這些夾在<item>與</item>、<name>與</name>、<addr> 與*</addr>之間的文本文字,
*像TiXmlAttribute指的就是<?xml version="1.0" encoding="UTF-8"?>節點中version、encoding,
*除此之外就是TiXmlUnknown。
以上轉載自別人博客!
有關TinyXml解析的文章很多,比如:
http://acnchen.i.sohu.com/blog/view/66703840.htm C++中使用tinyXML簡單例子
http://panpan.blog.51cto.com/489034/104961/ C++ XML解析之TinyXML篇
這兩篇文章都不錯,值得一看!
然而,對於複雜的xml字符串,這兩篇文章都沒有提到如何解析。於是,我研究了下,大體思路是:複雜的xml的特點是節點很多,並且經常出現節點嵌套節點。如何把每個節點的tag字段和內容字段提取出來是一個難題。這裏我想到的思路是:對每一個節點,如果存在子節點,就遞歸地提取子節點;如果不存在子節點,就提取該節點。通過使用遞歸函數能夠保證所有的節點都被提取到!示例代碼如下:
#include "tinyxml.h"
#include <vector>
//遞歸提取每個節點
void GetEleNameAndValue(TiXmlElement* pEle)
{
TiXmlElement* pEleTemp=NULL;
pEleTemp=pEle;
if(pEleTemp)
{
TiXmlElement* childEleTemp=pEleTemp->FirstChildElement();
while(childEleTemp)
{
GetEleNameAndValue(childEleTemp);
childEleTemp=childEleTemp->NextSiblingElement();
}
if(childEleTemp==NULL)
{
const char* pText=pEleTemp->GetText();
if(pText)
{
std::cout << pEleTemp->Value() <<":"<<pEleTemp->GetText()<<std::endl;
}
}
}
}
int main()
{
std::string xmlString = "<?xml version=\"1.0\" encoding=\"GBK\"?>\
<nlp>\
<version>1.0.0.5800</version>\
<rawtext>大話西遊</rawtext>\
<parsedtext>大話西遊 </parsedtext>\
<result>\
<focus>app</focus>\
<action>\
<operation>launch</operation>\
</action>\
<object>\
<name>大話西遊</name>\
</object>\
</result>\
<result>\
<focus>music</focus>\
<action>\
<operation>play</operation>\
</action>\
<object>\
<name>大話西遊</name>\
</object>\
</result>\
<result>\
<focus>dialog</focus>\
<object>\
<name>大話西遊</name>\
<topic>namecard</topic>\
</object>\
<content>我搜索了一下【大話西遊】:《大話西遊》是周星馳電影公司和大陸西影合作拍攝的一部經典的無厘頭搞笑片,成就了大話的經典傳奇。《大話西遊》把周星馳推到了後現代主義喜劇大師的位置,進而推動了無厘頭文化在中國的流行。電影“大話西遊”分爲《月光寶盒》和《仙履奇緣》這兩部。</content>\
</result>";
TiXmlDocument* myDocument = new TiXmlDocument();
myDocument->Parse(xmlString.c_str()); //提取xml字符串的聲明部分
TiXmlDeclaration* XmlDeclaration = myDocument->FirstChild()->ToDeclaration();
std::cout<<"----------XML Declaration:------------------"<<std::endl;
if(XmlDeclaration)
{
std::cout<<"Version: "<<XmlDeclaration->Version()<<std::endl;
std::cout<<"Standalone: "<<XmlDeclaration->Standalone()<<std::endl;
std::cout<<"Encoding: "<<XmlDeclaration->Encoding()<<std::endl;
}
//
TiXmlElement* rootElement = myDocument->RootElement(); //Class
TiXmlElement *ChildElement = rootElement->FirstChildElement();
while ( ChildElement )
{
GetEleNameAndValue(ChildElement);
ChildElement = ChildElement->NextSiblingElement();
}
return 0;
}