加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2dx 3.2 读写XML,基于tinyxml2封装的易使用,更灵活的XML

发布时间:2020-12-14 19:57:45 所属栏目:百科 来源:网络整理
导读:简介 cocos2dx 3.2读写XML使用的是tinyxml2库。tinyxml2是一个轻量的解析XML的开源库,C++编写,跨平台,内存占用很

简介

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 "";
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读