cocos2dx 3.2 读写XML,基于tinyxml2封装的易使用,更灵活的XML接口。中文国际化。

前端之家收集整理的这篇文章主要介绍了cocos2dx 3.2 读写XML,基于tinyxml2封装的易使用,更灵活的XML接口。中文国际化。前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

简介

cocos2dx 3.2读写XML使用的是tinyxml2库。tinyxml2是一个轻量的解析XML的开源库,C++编写,跨平台,内存占用很小。解析文件时,在内存中生成DOM模型,即文档对象模型,遍历这颗树读取想要的数据。

UserDefault类是一个引擎封装好的XML读取类,但是使用这个类读写的XML的文件名固定为UserDefault.xml,并且不能灵活定义文档结构。所以对有特殊XML需求的项目中,就不太适用了。而如果在项目中直接使用tinyxml2库,感觉还不是很方便,所以基于tinyxml2又封装了一个XMLManager类,使用起来更方便,并且能够灵活创建、读取不同结构的XML文件

XMLManager类同时提供了一个中文资源国际化的方法,一般小项目可能会用到,把中文存到XML文件中读取。

类图


代码

tinyxml2的使用方法可以参照一下如下代码代码的注释以及使用方法也写得比较详细。
文件
/*
 * WWXMLManager.h
 *
 *  Created on: 2014年5月20日
 *      Author: wly
 */

#ifndef _WWXMLMANAGER_H_
#define _WWXMLMANAGER_H_

#include "cocos2d.h"
//#include "tinyxml2.h"
#include "tinyxml2/tinyxml2.h"

/*
 *   属性类,这里属性是只读的,修改请使用WWXMLNode类
 *   <express name="test" value="nothing">This is a test!</express>
 *   name 和 value 就是结点的属性
 */
class WWXMLAttribute
{
public:

	WWXMLAttribute(const tinyxml2::XMLAttribute *pXMLAttribute);

	~WWXMLAttribute();

	//下一个属性值
	WWXMLAttribute next();

	//获取属性名称
	const char* getName();

	//获取string类型属性值
	const char* value();

	//获取int类型属性值
	int intValue();

	//获取bool类型属性值
	bool boolValue();

	//获取float类型属性值
	float floatValue();

	//获取double类型属性值
	double doubleValue();

	//返回是否是空
	bool isNULL();

private:
	//文档属性对象
	const tinyxml2::XMLAttribute *m_pXMLAttribute;
};


/*
 *  节点类,封装对节点的各种操作.
 *  如下类型节点
 *	<example name="ok",flag="1">text</example>
 *   
 *  example是 nodeName
 *  name和flag是attribute
 *  text是 nodeValue
 */
class WWXMLNode
{
public:

	WWXMLNode(tinyxml2::XMLElement *pXMLElem);

	WWXMLNode(tinyxml2::XMLElement *pXMLElem,tinyxml2::XMLDocument *pXMLDocument);

	~WWXMLNode();

	//增加子节点
	WWXMLNode addChildNode(const char* name);

	//查找子节点,默认返回第一个子节点
	WWXMLNode findChildNode(const char* name = NULL);

	//查找下一个兄弟节点,默认返回下面第一个兄弟节点
	WWXMLNode findSlibingNode(const char* name =NULL);

	//查找上一个兄弟节点,默认返回上面第一个兄弟节点
	WWXMLNode preSlibingNode(const char* name = NULL);

	//设置节点属性值
	void setAttributeValue(const char* name,const char* value);

	//获取指定的属性值
	const char* getAttributeValue(const char* name);

	//删除一个指定名称属性值
	void deleteAttribute(const char* name);

	//设置节点名称
	void setNodeName(const char* name);

	//获取节点名称
	const char* getNodeName();

	//设置节点值
	void setNodeValue(const char* value);

	//获取节点值
	const char* getNodeValue();

	//获取属性,默认返回第一个属性
	WWXMLAttribute firstAttribute(const char* name = NULL);

	//删除本节点
	void removeSelf();

	//删除所有子节点
	void removeAllChildNode();

	//是否是空节点
	bool isNULL();

private:
	tinyxml2::XMLDocument *m_pXMLDocument;
	tinyxml2::XMLElement *m_pXMLElem;
};

/*
 * XML管理类,使用tinyxml2封装了操作xml的细节,需要配合WWXMLNode类使用。
 * 封装了CCUserDefault提供的功能
 *
 * example:
 * WWXMLManager myXML;
 * myXML.createXMLFile("myXML.xml","TestXMLManager");
 * WWXMLNode itemNode = myXML.getXMLRootNode().addChildNode("item");
 * itemNode.setAttributeValue("flag","true");
 * myXML.saveXMLFile();
 */
class WWXMLManager
{
public:
	WWXMLManager();

	WWXMLManager(const char* strXMLPath);

	~WWXMLManager(void);

	//加载xml文件,utf-8格式文件
	bool loadXMLFile(const char* strXmlPath);

	//获取xml文件根目录值
	const char* getXMLRootKeyValue();

	//获取根结点
	WWXMLNode getXMLRootNode();

	//创建xml文件,默认为utf-8编码
	bool createXMLFile(const char* strFileName,const char* rootNode="root");

	//保存文件修改后需要调用方法
	bool saveXMLFile();

	/*
	 *  以下方法适用于引擎提供的默认XML文件,可使用getXMLFilePath获取文件路径
	 *  对应于CCUserDefault类
	 */
public:

	//根据key获取bool的值,当key值不存在时,返回defaultValue
	static bool getDefaultXMLBoolForKey(const char* pKey);
	static bool getDefaultXMLBoolForKey(const char* pKey,bool defaultValue);

	static int getDefaultXMLIntegerForKey(const char* pKey);
	static int getDefaultXMLIntegerForKey(const char* pKey,int defaultValue); 

	static float getDefaultXMLFloatForKey(const char* pKey);
	static float getDefaultXMLFloatForKey(const char* pKey,float defaultValue);

	static double getDefaultXMLDoubleForKey(const char* pKey);
	static double getDefaultXMLDoubleForKey(const char* pKey,double defaultValue);

	static std::string getDefaultXMLStringForKey(const char* pKey);
	static std::string getDefaultXMLStringForKey(const char* pKey,const std::string & defaultValue);

	//根据key值以bool设置值
	static void setDefaultXMLBoolForKey(const char* pKey,bool value);

    static void setDefaultXMLIntegerForKey(const char* pKey,int value);

    static void setDefaultXMLFloatForKey(const char* pKey,float value);

    static void setDefaultXMLDoubleForKey(const char* pKey,double value);

    static void setDefaultXMLStringForKey(const char* pKey,const std::string & value);

    static void purgeSharedUserDefault();

	//获取默认的XML文件路径
    const static std::string& getDefaultXMLFilePath();
	//xml文件是否存在
	static bool isXmlFileExist(const char* strFilePath);

	/*
	 *   说明:获取项目的字符串资源,类似如下的文件格式
	 *   参数:键值,段名值。
	 *   例子:
	 *   <?xml version="1.0" encoding="utf-8"?>
	 *   <resources>
	 *       <HallScene>
	 *           <string name="Str_app_name">项目名称</string> 
	 *           <string name="Str_chujiRoom">初级房</string> 
	 *       </HallScene>
	 *       <GameScene>
	 *           <string name="Str_app_name">项目名称</string> 
	 *       </GameScene>
	 *    </resources>
	 *
	 */
	static std::string getWWStringFromXML(const std::string &strKey,const std::string &strSection);

private:
	tinyxml2::XMLDocument *m_pXMLDocument;

	//文件路径,每次load时改变
	std::string m_strXMLFilePath;
};


#endif


实现:
/*
 * WWXMLManager.h
 *
 *  Created on: 2014年5月20日
 *      Author: wly
 */

#include "WWXMLManager.h"
#include "../WWMacros.h"
#include "WW_GBK_TO_UTF8.h"
USING_NS_CC;

WWXMLAttribute::WWXMLAttribute(const tinyxml2::XMLAttribute *pXMLAttribute):
m_pXMLAttribute(pXMLAttribute)
{
	
}

WWXMLAttribute::~WWXMLAttribute()
{

}

WWXMLAttribute WWXMLAttribute::next()
{
	if (m_pXMLAttribute)
	{
		return m_pXMLAttribute->Next();
	}
	return NULL;
}

const char* WWXMLAttribute::getName()
{
	if (m_pXMLAttribute)
	{
		const char* pName = m_pXMLAttribute->Name();
		if (pName)
		{
			return pName;
		}
	}
	return "";
}

const char* WWXMLAttribute::value()
{
	if (m_pXMLAttribute)
	{
		const char* pValue = m_pXMLAttribute->Value();
		if (pValue)
		{
			return pValue;
		}
	}
	return "";
}

int WWXMLAttribute::intValue()
{
	if (m_pXMLAttribute)
	{
		return m_pXMLAttribute->IntValue();
	}
	return -1;
}

bool WWXMLAttribute::boolValue()
{
	if (m_pXMLAttribute)
	{
		return m_pXMLAttribute->BoolValue();
	}
	return false;
}

float WWXMLAttribute::floatValue()
{
	if (m_pXMLAttribute)
	{
		return m_pXMLAttribute->FloatValue();
	}
	return -1;
}

double WWXMLAttribute::doubleValue()
{
	if (m_pXMLAttribute)
	{
		return m_pXMLAttribute->DoubleValue();
	}
	return -1;
}

bool WWXMLAttribute::isNULL()
{
	return NULL == m_pXMLAttribute;
}

WWXMLNode::WWXMLNode(tinyxml2::XMLElement *pElem):
m_pXMLElem(pElem),m_pXMLDocument(NULL)
{

}

WWXMLNode::WWXMLNode(tinyxml2::XMLElement *pElem,tinyxml2::XMLDocument *pDocument):
m_pXMLElem(pElem),m_pXMLDocument(pDocument)
{
	
}

WWXMLNode::~WWXMLNode()
{

}

WWXMLNode WWXMLNode::addChildNode(const char* name)
{
	if (m_pXMLElem && m_pXMLDocument)
	{
		tinyxml2::XMLElement *pElem = m_pXMLDocument->NewElement(name);
		if (pElem)
		{
			m_pXMLElem->LinkEndChild(pElem);
			WWXMLNode node(pElem,m_pXMLDocument);
			return node;
		}
	}
	return NULL;
}

WWXMLNode WWXMLNode::findChildNode(const char* name /* = NULL */)
{
	if (m_pXMLElem && m_pXMLDocument)
	{
		if (NULL == name)
		{
			WWXMLNode node(m_pXMLElem->FirstChildElement(),m_pXMLDocument);
			return node;
		}
		else
		{
			WWXMLNode node(m_pXMLElem->FirstChildElement(name),m_pXMLDocument);
			return node;	
		}
	}
	return NULL;
}

WWXMLNode WWXMLNode::findSlibingNode(const char* name /* =NULL */)
{
	if (m_pXMLElem && m_pXMLDocument)
	{
		if (NULL == name)
		{
			WWXMLNode node(m_pXMLElem->NextSiblingElement(),m_pXMLDocument);
			return node;
		}
		else
		{
			WWXMLNode node(m_pXMLElem->NextSiblingElement(name),m_pXMLDocument);
			return node;	
		}
	}
	return NULL;
}

WWXMLNode WWXMLNode::preSlibingNode(const char* name /* =NULL */)
{
	if (m_pXMLElem && m_pXMLDocument)
	{
		if (NULL == name)
		{
			WWXMLNode node(m_pXMLElem->PrevIoUsSiblingElement(),m_pXMLDocument);
			return node;
		}
		else
		{
			WWXMLNode node(m_pXMLElem->PrevIoUsSiblingElement(name),m_pXMLDocument);
			return node;	
		}
	}
	return NULL;
}

void WWXMLNode::setAttributeValue(const char* name,const char* value)
{
	if (m_pXMLElem && NULL != name)
	{
		m_pXMLElem->SetAttribute(name,value);
	}
}

const char* WWXMLNode::getAttributeValue(const char* name)
{
	if (m_pXMLElem && NULL != name)
	{
		const char* pName = m_pXMLElem->Attribute(name);
		if (NULL == pName)
		{
			return "";
		}
		return pName;
	}
	return "";
}

void WWXMLNode::deleteAttribute(const char* name)
{
	if (m_pXMLElem)
	{
		m_pXMLElem->DeleteAttribute(name);
	}
}

void WWXMLNode::setNodeName(const char* name)
{
	if (m_pXMLElem && NULL != name)
	{
		m_pXMLElem->SetName(name);
	}
}

const char* WWXMLNode::getNodeName()
{
	if (m_pXMLElem)
	{
		const char* pName = m_pXMLElem->Name();
		if (NULL == pName)
		{
			return "";
		}
		return pName;
	}
	return "";
}

void WWXMLNode::setNodeValue(const char* value)
{
	if (m_pXMLElem && m_pXMLDocument)
	{
		tinyxml2::XMLText *pText = m_pXMLDocument->NewText(value);
		m_pXMLElem->LinkEndChild(pText);
	}
}

const char* WWXMLNode::getNodeValue()
{
	if (m_pXMLElem)
	{
		const char* pValue = m_pXMLElem->GetText();
		if (NULL == pValue)
		{
			return "";
		}
		return pValue;
	}
	return "";
}

WWXMLAttribute WWXMLNode::firstAttribute(const char* name /*= NULL*/)
{
	if (m_pXMLElem)
	{
		if (NULL == name)
		{
			return m_pXMLElem->FirstAttribute();
		}
		else
		{
			WWXMLAttribute attribute = m_pXMLElem->FirstAttribute();
			while (!attribute.isNULL())
			{
				if (strcmp(name,attribute.getName()) == 0)
				{
					return attribute;
				}
				attribute = attribute.next();
			}
		}
		
	}
	return NULL;
}

void WWXMLNode::removeSelf()
{
	if (m_pXMLElem)
	{
		if (m_pXMLElem->Parent())
		{
			m_pXMLElem->Parent()->DeleteChild((tinyxml2::XMLNode*)m_pXMLElem);
		}
	}
}

void WWXMLNode::removeAllChildNode()
{
	if (m_pXMLElem)
	{
		m_pXMLElem->DeleteChildren();
	}
}

bool WWXMLNode::isNULL()
{
	return m_pXMLElem == NULL;
}


WWXMLManager::WWXMLManager():
m_pXMLDocument(NULL),m_strXMLFilePath("")
{

}

WWXMLManager::WWXMLManager(const char* strXMLPath):
m_pXMLDocument(NULL),m_strXMLFilePath(strXMLPath)
{
	loadXMLFile(strXMLPath);
}

WWXMLManager::~WWXMLManager(void)
{
	if (m_pXMLDocument)
	{
		delete m_pXMLDocument;
	}
}

bool WWXMLManager::loadXMLFile(const char* strXmlPath)
{
	//加载同一文件时,直接返回
	if (strcmp(m_strXMLFilePath.c_str(),strXmlPath) == 0)
	{
		return true;
	}

	m_strXMLFilePath = strXmlPath;
	//首先置空,防止重复加载
	if (m_pXMLDocument)
	{
		delete m_pXMLDocument;
		m_pXMLDocument = NULL;
	}

	m_pXMLDocument = new tinyxml2::XMLDocument();
	if (NULL == m_pXMLDocument)
	{
		return false;
	}

	//使用文件内容加载,直接加载可能会有兼容性问题,字符流内存需要手动释放
	std::string strXmlBuffer = CCFileUtils::getInstance()->getStringFromFile(strXmlPath);
	if (strXmlBuffer.empty())
	{
		CCLOG("WWXMLManager::%s file data is empty!",strXmlPath);
		return false;
	}

	//解析XML字符流
	if (tinyxml2::XML_SUCCESS != m_pXMLDocument->Parse(strXmlBuffer.c_str(),strXmlBuffer.length()))
	{
		CCLOG("WWXMLManager::%s Parse data error!",strXmlPath);
		return false;
	}

	return true;
}

const char* WWXMLManager::getXMLRootKeyValue()
{
	if (m_pXMLDocument)
	{
		return getXMLRootNode().getNodeName();
	}
	return "";
}

WWXMLNode WWXMLManager::getXMLRootNode()
{
	if (m_pXMLDocument)
	{
		WWXMLNode node(m_pXMLDocument->RootElement(),m_pXMLDocument);
		return node;
	}
	return NULL;
}

bool WWXMLManager::createXMLFile(const char* strFileName,const char* rootNode/* ="root" */)
{
	//利用tinyxml2方法创建xml文件
	tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument(); 
	if (NULL == pDoc)  
	{  
		return false;  
	}  

	bool bRet = false;
	do 
	{
		tinyxml2::XMLDeclaration *pDeclaration = pDoc->NewDeclaration(NULL);
		if (NULL == pDeclaration)  
		{  
			bRet = false;  
			break;
		}  
		pDoc->LinkEndChild(pDeclaration); 
		tinyxml2::XMLElement *pRootEle = pDoc->NewElement(rootNode);  
		if (NULL == pRootEle)  
		{  
			bRet = false;  
			break;  
		}  
		pDoc->LinkEndChild(pRootEle);  

		if (tinyxml2::XML_SUCCESS != pDoc->SaveFile(strFileName))
		{
			bRet = false;  
			break;
		}
		bRet = true;
	} while (0);

	if(pDoc)
	{
		delete pDoc;
	}

	//创建成功后加载
	loadXMLFile(strFileName);

	return bRet;
}

bool WWXMLManager::saveXMLFile()
{
	if (m_pXMLDocument)
	{
		if (tinyxml2::XML_SUCCESS != m_pXMLDocument->SaveFile(m_strXMLFilePath.c_str()))
		{
			return false;
		}
	}
	return true;
}

bool WWXMLManager::getDefaultXMLBoolForKey(const char* pKey)
{
	return CCUserDefault::getInstance()->getBoolForKey(pKey);
}

bool WWXMLManager::getDefaultXMLBoolForKey(const char* pKey,bool defaultValue)
{
	return CCUserDefault::getInstance()->getBoolForKey(pKey,defaultValue);
}

int WWXMLManager::getDefaultXMLIntegerForKey(const char* pKey)
{
	return CCUserDefault::getInstance()->getIntegerForKey(pKey);
}

int WWXMLManager::getDefaultXMLIntegerForKey(const char* pKey,int defaultValue)
{
	return CCUserDefault::getInstance()->getIntegerForKey(pKey,defaultValue);
}

float WWXMLManager::getDefaultXMLFloatForKey(const char* pKey)
{
	return CCUserDefault::getInstance()->getFloatForKey(pKey);
}

float WWXMLManager::getDefaultXMLFloatForKey(const char* pKey,float defaultValue)
{
	return CCUserDefault::getInstance()->getFloatForKey(pKey,defaultValue);
}

double WWXMLManager::getDefaultXMLDoubleForKey(const char* pKey)
{
	return CCUserDefault::getInstance()->getDoubleForKey(pKey);
}

double WWXMLManager::getDefaultXMLDoubleForKey(const char* pKey,double defaultValue)
{
	return CCUserDefault::getInstance()->getDoubleForKey(pKey,defaultValue);
}

std::string WWXMLManager::getDefaultXMLStringForKey(const char* pKey)
{
	return CCUserDefault::getInstance()->getStringForKey(pKey);
}

std::string WWXMLManager::getDefaultXMLStringForKey(const char* pKey,const std::string & defaultValue)
{
	return CCUserDefault::getInstance()->getStringForKey(pKey,defaultValue);
}

void WWXMLManager::setDefaultXMLBoolForKey(const char* pKey,bool value)
{
	CCUserDefault::getInstance()->setBoolForKey(pKey,value);
}

void WWXMLManager::setDefaultXMLIntegerForKey(const char* pKey,int value)
{
	CCUserDefault::getInstance()->setIntegerForKey(pKey,value);
}

void WWXMLManager::setDefaultXMLFloatForKey(const char* pKey,float value)
{
	CCUserDefault::getInstance()->setFloatForKey(pKey,value);
}

void WWXMLManager::setDefaultXMLDoubleForKey(const char* pKey,double value)
{
	CCUserDefault::getInstance()->setDoubleForKey(pKey,value);
}

void WWXMLManager::setDefaultXMLStringForKey(const char* pKey,const std::string & value)
{
	CCUserDefault::getInstance()->setStringForKey(pKey,value);
}

void WWXMLManager::purgeSharedUserDefault()
{
	CCUserDefault::getInstance()->destroyInstance();
}

const std::string& WWXMLManager::getDefaultXMLFilePath()
{
	return CCUserDefault::getInstance()->getXMLFilePath();
}

bool WWXMLManager::isXmlFileExist(const char* strFilePath)
{	
	FILE *fp = fopen(strFilePath,"r");
	bool bRet = false;

	if (fp)
	{
		bRet = true;
		fclose(fp);
	}

	return bRet;
}

std::string WWXMLManager::getWWStringFromXML(const std::string &strKey,const std::string &strSection)
{
	if (strKey.empty() || strSection.empty())
	{
		CCLOG("key or section is empty!");
		return "";
	}

	//加载XML文件
	WWXMLManager myXML;
	if (!myXML.loadXMLFile(WWSTRING_XML_PATH.c_str()))
	{
		CCLOG("load string resource error!");
		return "";
	}

	//循环获取节点名为stirng,属性名为name,属性值为strKey的节点
	WWXMLNode node = myXML.getXMLRootNode().findChildNode(strSection.c_str());
	if (!node.isNULL())
	{
		WWXMLNode childNode = node.findChildNode("string");
		while (!childNode.isNULL())
		{
			if (strcmp(childNode.firstAttribute("name").value(),strKey.c_str()) == 0)
			{

				std::string strResult = childNode.getNodeValue();
				//win32,模拟器上显示需要转换成gbk编码
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
				GBKToUTF8(strResult,"GBK","UTF-8");
#endif
				return strResult;
			}
			childNode = childNode.findSlibingNode("string");
		}
	}

	return "";
}

猜你在找的Cocos2d-x相关文章