cocos2d-x中对xml的解析是采用的TinyXML库,而对plist的解析同时结合了CCDictionary来处理,这里简单介绍下cocos2d-x中解析xml的两种方式,也是常用的xml两个C++解析库:TinyXML和RapidXML。xml被设计用于数据存储和传输,重点是数据内容本身,而不像html,用于表现数据。
TinyXML
概况
TinyXML的主页,本来不打算介绍这个库的,因为它的解析效率并不高,但是鉴于cocos2d-x采用的就是它,所以也稍微写一下它的用法,cocos2d-x使用的是TinyXML2,Github地址在这里。就是对TinyXML重新进行了封装,具体的区别在其github上也写的很清楚了。
示例
这里不介绍API,因为太多了,在线手册也都有。首先下载TinyXML库,将4个cpp文件和2个h文件加入cocos2d-x中。添加头文件时只需添加”tinyxml.h“即可。
xml的创建
xml的创建1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| void TestLayer::writeTinyXML() { TiXmlDocument* myTinyXMLDoc=new TiXmlDocument(); TiXmlElement* rootElement=new TiXmlElement("Jacky"); myTinyXMLDoc->LinkEndChild(rootElement); TiXmlElement* infoElement=new TiXmlElement("Info"); rootElement->LinkEndChild(infoElement); infoElement->SetAttribute("Name","Jacky"); infoElement->SetAttribute("QQ","754505629"); infoElement->SetAttribute("E-mail","Geek.Jacky@Gmail.com"); TiXmlElement* blogElement=new TiXmlElement("blog"); infoElement->LinkEndChild(blogElement); TiXmlText* blogtext=new TiXmlText("http://blog.csdn.net/jackystudio"); blogElement->LinkEndChild(blogtext); TiXmlElement* websiteElenment=new TiXmlElement("website"); infoElement->LinkEndChild(websiteElenment); TiXmlText* websitetext=new TiXmlText("http://fusijie.github.io"); websiteElenment->LinkEndChild(websitetext); myTinyXMLDoc->SaveFile(CCFileUtils::sharedFileUtils()->fullPathForFilename("testTiny.xml").c_str()); delete myTinyXMLDoc; }
|
是不是很奇怪为什么new了那么多内存,但最后只delete TixmlDocument呢?其实在TinyXML中,子节点的内存管理都由父节点进行维护,所以不必在释放内存时对每个子节点都进行释放,而只需要释放父节点即可。
xml的读取
xml的读取1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| void TestLayer::readTinyXML() { TiXmlDocument* myTinyXMLDoc=new TiXmlDocument(CCFileUtils::sharedFileUtils()->fullPathForFilename("testTiny.xml").c_str()); myTinyXMLDoc->LoadFile(); TiXmlElement* rootElement = myTinyXMLDoc->RootElement(); TiXmlElement* infoElement = rootElement->FirstChildElement(); while (infoElement) { TiXmlAttribute* attributeOfinfo = infoElement->FirstAttribute(); while ( attributeOfinfo ) { CCLOG("%s : %s",attributeOfinfo->Name(),attributeOfinfo->Value()); attributeOfinfo = attributeOfinfo->Next(); } TiXmlElement* blogElement = infoElement->FirstChildElement(); CCLOG("blog : %s",blogElement->GetText()); TiXmlElement* websiteElement = blogElement->NextSiblingElement(); CCLOG("website : %s",websiteElement->GetText()); infoElement = infoElement->NextSiblingElement(); } delete myTinyXMLDoc; }
|
RapidXML
概况
RapidXML的主页。在其手册中第四节comparison with others parsers可以看到在同等条件下它的解析效率是TinyXML的30到60倍,所以如果需要解析大文件的话,RapidXML是不二之选。
示例
首先下载RapidXML库,将四个hpp文件都加入cocos2d-x中,在包含头文件时,4个hpp都要进行包含。
xml的创建
xml的创建1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| void TestLayer::writeRapidXML() { rapidxml::xml_document<> myRapidXMLDoc; rapidxml::xml_node<>* root = myRapidXMLDoc.allocate_node(rapidxml::node_element,"Jacky",NULL);//创建根节点 myRapidXMLDoc.append_node(root);//追加根节点 rapidxml::xml_node<>* info = myRapidXMLDoc.allocate_node(rapidxml::node_element,"Info",NULL);//创建info节点 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节点到root //创建blog和website节点并追加到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://fusijie.github.io"); 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; }
|
xml的读取
xml的读取1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| void TestLayer::readRapidXML() { rapidxml::file<> fdoc(CCFileUtils::sharedFileUtils()->fullPathForFilename("testRapid.xml").c_str()); CCLog(fdoc.data()); rapidxml::xml_document<> myRapidXMLDoc; myRapidXMLDoc.parse<0>(fdoc.data()); rapidxml::xml_node<>* root = myRapidXMLDoc.first_node(); rapidxml::xml_node<>* info = root->first_node(); rapidxml::xml_attribute<>* info_attr = info->first_attribute(); 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(); CCLog("%s:%s",blog->name(),blog->value()); rapidxml::xml_node<>* website=blog->next_sibling(); CCLog("%s:%s",website->name(),website->value()); }
|
生成xml的文件
以上2种方式生成的xml文件内容如下:
生成的xml文件1 2 3 4 5 6
| <Jacky> <Info Name="Jacky" QQ="754505629" E-mail="Geek.Jacky@Gmail.com"> <blog>http://blog.csdn.net/jackystudio</blog> <website>http://fusijie.github.io</website> </Info> </Jacky>
|
源码下载
下载地址