cocos2dx 2.2.5版里集成的tinyxml2不好用,总是报错,这里使用独立的第三方tinyxml库。
TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows,Linux中,mac上编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。
DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系。
准备
去官网下载tinyxml包后解压,将
tinystr.cpp
tinystr.h
tinyxml.cpp
tinyxml.h
tinyxmlerror.cpp
tinyxmlparser.cpp
测试
首先包含头文件#include "tinyxml.h"
创建xml文件
- voidHelloWorld::createXML()
- {
- //创建一个XML的文档对象。
- TiXmlDocument*myDocument=newTiXmlDocument();
- //创建xml文档声明并连接
- TiXmlDeclaration*declaration=newTiXmlDeclaration("1.0","UTF-8","");
- myDocument->LinkEndChild(declaration);
- //创建一个根元素并连接。
- TiXmlElement*RootElement=newTiXmlElement("Class");
- myDocument->LinkEndChild(RootElement);
- //创建一个Student元素并连接。
- TiXmlElement*student1=newTiXmlElement("Student");
- RootElement->LinkEndChild(student1);
- //设置Student元素的属性。
- student1->SetAttribute("ID","1");
- student1->SetAttribute("sex","boy");
- student1->SetAttribute("hobby","fight");
- //创建name元素、age元素并连接。
- TiXmlElement*NameElement1=newTiXmlElement("name");
- TiXmlElement*AgeElement1=newTiXmlElement("age");
- student1->LinkEndChild(NameElement1);
- student1->LinkEndChild(AgeElement1);
- //设置name元素和age元素的内容并连接。
- TiXmlText*NameContent1=newTiXmlText("LingHuchong");
- TiXmlText*AgeContent1=newTiXmlText("22");
- NameElement1->LinkEndChild(NameContent1);
- AgeElement1->LinkEndChild(AgeContent1);
- //创建另一个Student元素并连接。
- TiXmlElement*student2=newTiXmlElement("Student");
- RootElement->LinkEndChild(student2);
- //设置Student元素的属性。
- student2->SetAttribute("ID","2");
- student2->SetAttribute("sex","girl");
- student2->SetAttribute("hobby","dance");
- //创建name元素、age元素并连接。
- TiXmlElement*NameElement2=newTiXmlElement("name");
- TiXmlElement*AgeElement2=newTiXmlElement("age");
- student2->LinkEndChild(NameElement2);
- student2->LinkEndChild(AgeElement2);
- //设置name元素和age元素的内容并连接。
- TiXmlText*NameContent2=newTiXmlText("RenYingying");
- TiXmlText*AgeContent2=newTiXmlText("18");
- NameElement2->LinkEndChild(NameContent2);
- AgeElement2->LinkEndChild(AgeContent2);
- //设置文件名,这是在cocos2dx里的路径写法,在标准c++中可以用string类型的绝对或相对路径字符串
- std::stringPath=CCFileUtils::sharedFileUtils()->getWritablePath()+"test.xml";
- myDocument->SaveFile(Path.c_str());//保存到文件
- //删除文档对象
- deletemyDocument;
- }
void HelloWorld::createXML() { //创建一个XML的文档对象。 TiXmlDocument *myDocument = new TiXmlDocument(); //创建xml文档声明并连接 TiXmlDeclaration *declaration = new TiXmlDeclaration("1.0","UTF-8",""); myDocument->LinkEndChild(declaration); //创建一个根元素并连接。 TiXmlElement *RootElement = new TiXmlElement("Class"); myDocument->LinkEndChild(RootElement); //创建一个Student元素并连接。 TiXmlElement *student1 = new TiXmlElement("Student"); RootElement->LinkEndChild(student1); //设置Student元素的属性。 student1->SetAttribute("ID","1"); student1->SetAttribute("sex","boy"); student1->SetAttribute("hobby","fight"); //创建name元素、age元素并连接。 TiXmlElement *NameElement1 = new TiXmlElement("name"); TiXmlElement *AgeElement1 = new TiXmlElement("age"); student1->LinkEndChild(NameElement1); student1->LinkEndChild(AgeElement1); //设置name元素和age元素的内容并连接。 TiXmlText *NameContent1 = new TiXmlText("Ling Huchong"); TiXmlText *AgeContent1 = new TiXmlText("22"); NameElement1->LinkEndChild(NameContent1); AgeElement1->LinkEndChild(AgeContent1); //创建另一个Student元素并连接。 TiXmlElement *student2 = new TiXmlElement("Student"); RootElement->LinkEndChild(student2); //设置Student元素的属性。 student2->SetAttribute("ID","2"); student2->SetAttribute("sex","girl"); student2->SetAttribute("hobby","dance"); //创建name元素、age元素并连接。 TiXmlElement *NameElement2 = new TiXmlElement("name"); TiXmlElement *AgeElement2 = new TiXmlElement("age"); student2->LinkEndChild(NameElement2); student2->LinkEndChild(AgeElement2); //设置name元素和age元素的内容并连接。 TiXmlText *NameContent2 = new TiXmlText("Ren Yingying"); TiXmlText *AgeContent2 = new TiXmlText("18"); NameElement2->LinkEndChild(NameContent2); AgeElement2->LinkEndChild(AgeContent2); //设置文件名,这是在cocos2dx里的路径写法,在标准c++中可以用string类型的绝对或相对路径字符串 std::string Path = CCFileUtils::sharedFileUtils()->getWritablePath() + "test.xml"; myDocument->SaveFile(Path.c_str());//保存到文件 //删除文档对象 delete myDocument; }
以上代码创建的xml文件如下
- <?xmlversion="1.0"encoding="UTF-8"?>
- <Class>
- <StudentID="1"sex="boy"hobby="fight">
- <name>LingHuchong</name>
- <age>22</age>
- </Student>
- <StudentID="2"sex="girl"hobby="dance">
- <name>RenYingying</name>
- <age>18</age>
- </Student>
- </Class>
<?xml version="1.0" encoding="UTF-8" ?> <Class> <Student ID="1" sex="boy" hobby="fight"> <name>Ling Huchong</name> <age>22</age> </Student> <Student ID="2" sex="girl" hobby="dance"> <name>Ren Yingying</name> <age>18</age> </Student> </Class>解析xml文件
- voidHelloWorld::parseXML()
- {
- std::stringPath=CCFileUtils::sharedFileUtils()->getWritablePath()+"test.xml";
- //创建一个XML的文档对象。
- TiXmlDocument*myDocument=newTiXmlDocument(Path.c_str());
- myDocument->LoadFile();
- //或者这样写
- /*TiXmlDocument*myDocument=newTiXmlDocument();
- myDocument->LoadFile(Path.c_str());*/
- TiXmlElement*rootElement=myDocument->RootElement();//Class
- TiXmlElement*studentElement=rootElement->FirstChildElement();//Students
- //遍历第一层结点
- while(studentElement)
- {
- TiXmlAttribute*attributeOfStudent=studentElement->FirstAttribute();//获得student的第一个属性
- //遍历student的属性
- while(attributeOfStudent)
- {
- CCLog("%s:%s",attributeOfStudent->Name(),attributeOfStudent->Value());//打印键值对
- attributeOfStudent=attributeOfStudent->Next();
- }
- TiXmlElement*Element=studentElement->FirstChildElement();//获得student的第一个元素
- //遍历student的元素
- while(Element)
- {
- CCLog("%s:%s",Element->Value(),Element->GetText());//打印键值对
- Element=Element->NextSiblingElement();
- }
- studentElement=studentElement->NextSiblingElement();
- }
- //删除文档对象
- deletemyDocument;
- }
void HelloWorld::parseXML() { std::string Path = CCFileUtils::sharedFileUtils()->getWritablePath() + "test.xml"; //创建一个XML的文档对象。 TiXmlDocument *myDocument = new TiXmlDocument(Path.c_str()); myDocument->LoadFile(); //或者这样写 /*TiXmlDocument *myDocument = new TiXmlDocument(); myDocument->LoadFile(Path.c_str());*/ TiXmlElement* rootElement = myDocument->RootElement(); //Class TiXmlElement* studentElement = rootElement->FirstChildElement(); //Students //遍历第一层结点 while (studentElement) { TiXmlAttribute* attributeOfStudent = studentElement->FirstAttribute(); //获得student的第一个属性 //遍历student的属性 while (attributeOfStudent) { CCLog("%s:%s",attributeOfStudent->Value()); //打印键值对 attributeOfStudent = attributeOfStudent->Next(); } TiXmlElement* Element = studentElement->FirstChildElement();//获得student的第一个元素 //遍历student的元素 while (Element) { CCLog("%s:%s",Element->GetText()); //打印键值对 Element = Element->NextSiblingElement(); } studentElement = studentElement->NextSiblingElement(); } //删除文档对象 delete myDocument; }
说明
关于TinyXML基本使用:
XML文档的结构:
TinyXml实现的时DOM访问模型,主要类间的关系如下图所示:
TiXmlBase:其他类的基类,是个抽象类
TiXmlNode:表示一个节点,包含一般方法,如访问自节点、兄弟节点、编辑自身、编辑子节点
TiXmlDocument:表示整个XML文档,不对应其中某个特定的节点。
TiXmlElement:表示元素节点,可以包含子节点和TiXmlAttribute
TiXmlComment:表示注释
TiXmlDeclaration:表示声明
TiXmlText:表示文本节点
TiXmlUnknown:表示未知节点,通常是出错了
TiXmlAttribute:表示一个元素的属性
注意:
在标准c++工程中这个库可以解析带有带有中文的xml文件,并cout打印到屏幕,不过在cocos2dx中的中文解析出来cclog打印就乱码,需要iconv库的支持。