在编写读取.xml文件的功能时,参考网上的资料各种问题,所以不才写出以下测试用例,供程序新人作为参考使用吧。
(1) 创建UTF-8格式的.xml,命名为Item.xml,数据如下(已加注释,如果若要使用,请去掉注释):
1 // 物品ID1 // 物品类型:装备,材料,消耗品天马流星锤 // 物品名字你想砸谁,就砸谁 // 物品描述10 // 力量加成10 // 使用最小等级限制10 // 强化最大等级限制1.0 // 速度加成300 // 出售价格3 1 青龙炎月刀 听着名字就霸气 10 20 30 3.0 600
(2) 接下来,创建头文件,如XmlItem.h,代码如下:
#ifndef __XML_ITEM_H__#define __XML_ITEM_H__#include "cocos2d.h"#include "support/tinyxml2/tinyxml2.h"USING_NS_CC;using namespace std;/*解析物品文件:Item.xml*/// 物品typedef struct sItem{ int Id; // ID int type; // 类型:装备,材料,消耗品 string name; // 名字 string state; // 描述 int useMinLev; // 使用最小等级限制 int StrengthMaxLev; // 强化最大等级限制 int power; // 力量加成 int speed; // 速度加成 int sprice; // 价格 }ITEMDATA;// 物品数据类 // 编写的缘故:是由于个人已经习惯使用std::map来存储数据,然而鉴于cocos2d-x的内存管理机制且推荐cocos2d-x自带的CCDictionary进行 // 存储,但是CCDictionary::setObject(CCObject* pObject, intptr_t key)使用CCObject* pObject对象,所以该类要继承CCNodeclass Item : public cocos2d::CCNode{public: Item(); void CleanItemData();public: ITEMDATA data;};// 文件解析类class XmlItem : public cocos2d::CCNode{public: XmlItem(); ~XmlItem(); static XmlItem* GetInstance(); void AnalyticItemXml(const char* fileName); // 解析Item.xml文件 private: static XmlItem* m_pInstance; CCDictionary* m_pDicItem;};#endif
(3) 剩下的不用多说,来编写XmlItem.cpp,代码如下:
#include "XmlItem.h"/// ItemItem::Item(){ CleanItemData();}void Item::CleanItemData(){ memset(&data,0x00,sizeof(data));}//文件解析XmlItem* XmlItem::m_pInstance = NULL;XmlItem::XmlItem(){ m_pDicItem = CCDictionary::create(); m_pDicItem->retain(); // 需要添加,否则会导致崩溃,不信,可以注释掉试试 }XmlItem::~XmlItem(){ CC_SAFE_DELETE(m_pDicItem);}XmlItem* XmlItem::GetInstance(){ if(m_pInstance == NULL) { m_pInstance = new XmlItem(); } return m_pInstance;}void XmlItem::AnalyticItemXml( const char* fileName ){ std::string filepath = CCFileUtils::sharedFileUtils()->fullPathForFilename(fileName); tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument(); tinyxml2::XMLError errorId = pDoc->LoadFile(filepath.c_str()); if(errorId != 0) { CCLOG("xml anlyatic error: %s",fileName); return; } // 获取根元素 tinyxml2::XMLElement *pElement = pDoc->RootElement(); // 获取第一个子节点 tinyxml2::XMLElement *rootElement = pElement->FirstChildElement(); while(rootElement != NULL) { Item* pItem = new Item(); // 获取节点的子级 tinyxml2::XMLNode *pCurNode = rootElement->FirstChild(); while(pCurNode != NULL) { // 查阅资料说,使用pCurNode->ToElement->GetText() 这样不安全,会导致内存泄露,但至今仍没有找到更好的方法,见谅 if(!strcmp(pCurNode->Value(),"ItemType")) pItem->data.type = atoi(pCurNode->ToElement()->GetText()); else if(!strcmp(pCurNode->Value(),"ItemId")) pItem->data.Id = atoi(pCurNode->ToElement()->GetText()); else if(!strcmp(pCurNode->Value(),"Name")) pItem->data.name = pCurNode->ToElement()->GetText(); else if(!strcmp(pCurNode->Value(),"ItemState")) pItem->data.state = pCurNode->ToElement()->GetText(); else if(!strcmp(pCurNode->Value(),"power")) pItem->data.power = atoi(pCurNode->ToElement()->GetText()); else if(!strcmp(pCurNode->Value(),"price")) pItem->data.sprice = atoi(pCurNode->ToElement()->GetText()); // 获取该节点的下一子级 pCurNode = pCurNode->NextSibling(); } m_pDicItem->setObject(pItem,pItem->data.Id); // 进入下一个节点 rootElement = rootElement->NextSiblingElement(); }}
如果大家有什么更好的方法,希望给其建议,谢谢大家。