原創(chuàng )作品,轉載請標明:
http://blog.csdn.net/jackystudio/article/details/17409381cocos2d-x中對xml的解析是采用的TinyXML庫,而對plist的解析同時(shí)結合了CCDictionary來(lái)處理,這里簡(jiǎn)單介紹下cocos2d-x中解析xml的兩種方式,也是常用的xml兩個(gè)C++解析庫:TinyXML和RapidXML。xml被設計用于數據存儲和傳輸,重點(diǎn)是數據內容本身,而不像html,用于表現數據。
1.TinyXML
1.1.概況
TinyXML的主頁(yè)是
http://www.grinninglizard.com/tinyxml/,本來(lái)不打算介紹這個(gè)庫的,因為它的解析效率并不高,但是鑒于cocos2d-x采用的就是它,所以也稍微寫(xiě)一下它的用法,cocos2d-x使用的是TinyXML2,Github地址在
https://github.com/leethomason/tinyxml2。就是對TinyXML重新進(jìn)行了封裝,具體的區別在其github上也寫(xiě)的很清楚了。
1.2.示例
這里不介紹API,因為太多了,在線(xiàn)手冊也都有。首先下載TinyXML庫,將4個(gè)cpp文件和2個(gè)h文件加入cocos2d-x中。添加頭文件時(shí)只需添加"tinyxml.h"即可。
1.2.1.xml的創(chuàng )建
[cpp]
view plaincopyvoid TestLayer::writeTinyXML()
{
TiXmlDocument* myTinyXMLDoc=new TiXmlDocument();//創(chuàng )建文檔對象
TiXmlElement* rootElement=new TiXmlElement("Jacky");//創(chuàng )建根節點(diǎn)并連接到文檔
myTinyXMLDoc->LinkEndChild(rootElement);
TiXmlElement* infoElement=new TiXmlElement("Info");//創(chuàng )建info節點(diǎn)并連接到根節點(diǎn)
rootElement->LinkEndChild(infoElement);
infoElement->SetAttribute("Name","Jacky");//為info節點(diǎn)設置屬性
infoElement->SetAttribute("QQ","754505629");
infoElement->SetAttribute("E-mail","Geek.Jacky@Gmail.com");
TiXmlElement* blogElement=new TiXmlElement("blog");
infoElement->LinkEndChild(blogElement);//創(chuàng )建blog節點(diǎn)并連接到info節點(diǎn)
TiXmlText* blogtext=new TiXmlText("http://blog.csdn.net/jackystudio");
blogElement->LinkEndChild(blogtext);//為blog節點(diǎn)添加文本值
TiXmlElement* websiteElenment=new TiXmlElement("website");
infoElement->LinkEndChild(websiteElenment);
TiXmlText* websitetext=new TiXmlText("http://www.fusijie.com");
websiteElenment->LinkEndChild(websitetext);
myTinyXMLDoc->SaveFile(CCFileUtils::sharedFileUtils()->fullPathForFilename("testTiny.xml").c_str());//保存xml
delete myTinyXMLDoc;
}
是不是很奇怪為什么new了那么多內存,但最后只delete TixmlDocument呢?其實(shí)在TinyXML中,子節點(diǎn)的內存管理都由父節點(diǎn)進(jìn)行維護,所以不必在釋放內存時(shí)對每個(gè)子節點(diǎn)都進(jìn)行釋放,而只需要釋放父節點(diǎn)即可。
1.2.2.xml的讀取
[cpp]
view plaincopyvoid TestLayer::readTinyXML()
{
TiXmlDocument* myTinyXMLDoc=new TiXmlDocument(CCFileUtils::sharedFileUtils()->fullPathForFilename("testTiny.xml").c_str());
myTinyXMLDoc->LoadFile();
TiXmlElement* rootElement = myTinyXMLDoc->RootElement(); //獲取根節點(diǎn)
TiXmlElement* infoElement = rootElement->FirstChildElement(); // 獲取Info節點(diǎn)
while (infoElement)
{
TiXmlAttribute* attributeOfinfo = infoElement->FirstAttribute(); //獲得info的屬性
while ( attributeOfinfo )
{
CCLOG("%s : %s",attributeOfinfo->Name(),attributeOfinfo->Value());//獲取所有屬性
attributeOfinfo = attributeOfinfo->Next();
}
TiXmlElement* blogElement = infoElement->FirstChildElement();//獲得blog
CCLOG("blog : %s",blogElement->GetText());
TiXmlElement* websiteElement = blogElement->NextSiblingElement();//獲取website
CCLOG("website : %s",websiteElement->GetText());
infoElement = infoElement->NextSiblingElement();//查找下一節點(diǎn)
}
delete myTinyXMLDoc;
}
2.RapidXML
2.1.概況
RapidXML的主頁(yè)是
http://rapidxml.sourceforge.net/。在其手冊中第四節
comparison with others parsers可以看到在同等條件下它的解析效率是TinyXML的30到60倍,所以如果需要解析大文件的話(huà),RapidXML是不二之選。
2.2.示例
首先下載RapidXML庫,將四個(gè)hpp文件都加入cocos2d-x中,在包含頭文件時(shí),4個(gè)hpp都要進(jìn)行包含。
2.2.1.xml的創(chuàng )建
[cpp]
view plaincopyvoid TestLayer::writeRapidXML()
{
rapidxml::xml_document<> myRapidXMLDoc;
rapidxml::xml_node<>* root = myRapidXMLDoc.allocate_node(rapidxml::node_element,"Jacky",NULL);//創(chuàng )建根節點(diǎn)
myRapidXMLDoc.append_node(root);//追加根節點(diǎn)
rapidxml::xml_node<>* info = myRapidXMLDoc.allocate_node(rapidxml::node_element,"Info",NULL);//創(chuàng )建info節點(diǎn)
info->append_attribute(myRapidXMLDoc.allocate_attribute("Name","Jacky"));
info->append_attribute(myRapidXMLDoc.allocate_attribute("QQ","754505629"));
info->append_attribute(myRapidXMLDoc.allocate_attribute("E-mail","Geek.Jacky@Gmail.com"));
root->append_node(info);//追加info節點(diǎn)到root
//創(chuàng )建blog和website節點(diǎn)并追加到root
rapidxml::xml_node<>* blog = myRapidXMLDoc.allocate_node(rapidxml::node_element,"blog","http://blog.csdn.net/jackystudio");
info->append_node(blog);
rapidxml::xml_node<>* website = myRapidXMLDoc.allocate_node(rapidxml::node_element,"website","http://www.fusijie.com");
info->append_node(website);
//保存xml文檔
std::string text;
rapidxml::print(std::back_inserter(text), myRapidXMLDoc, 0);
CCLog(text.c_str());
std::ofstream out(CCFileUtils::sharedFileUtils()->fullPathForFilename("testRapid.xml"));
out << myRapidXMLDoc;
}
2.2.2.xml的讀取
[cpp]
view plaincopyvoid TestLayer::readRapidXML()
{
rapidxml::file<> fdoc(CCFileUtils::sharedFileUtils()->fullPathForFilename("testRapid.xml").c_str());//讀取數據
CCLog(fdoc.data());
rapidxml::xml_document<> myRapidXMLDoc;
myRapidXMLDoc.parse<0>(fdoc.data());//將數據寫(xiě)入xml_document
rapidxml::xml_node<>* root = myRapidXMLDoc.first_node();//獲取根節點(diǎn)
rapidxml::xml_node<>* info = root->first_node();//獲取Info節點(diǎn)
rapidxml::xml_attribute<>* info_attr = info->first_attribute();//獲取info屬性
CCLog("%s:%s",info_attr->name(),info_attr->value());
CCLog("%s:%s",info_attr->next_attribute()->name(),info_attr->next_attribute()->value());
CCLog("%s:%s",info_attr->next_attribute()->next_attribute()->name(),info_attr->next_attribute()->next_attribute()->value());
rapidxml::xml_node<>* blog=info->first_node();//獲取blog節點(diǎn)
CCLog("%s:%s",blog->name(),blog->value());
rapidxml::xml_node<>* website=blog->next_sibling();//獲取website節點(diǎn)
CCLog("%s:%s",website->name(),website->value());
}
3.生成xml的文件
以上2種方式生成的xml文件內容如下:
[html]
view plaincopy<Jacky>
<Info Name="Jacky" QQ="754505629" E-mail="Geek.Jacky@Gmail.com">
<blog>http://blog.csdn.net/jackystudio</blog>
<website>http://www.fusijie.com</website>
</Info>
</Jacky>
4.源碼下載
下載地址:
http://download.csdn.net/detail/jackyvincefu/6732361