封装tinyxml实现对UTF8和UNICODE编码格式转换

    tinyxml对存储xml非常方便,但存储的格式却不是UTF8,导致实际使用中遇到读取问题。

    为了方便使用,借助对C++ 保存文件为UTF8编码格式学习,实现对tinyxml的数据转换做了一些封装,使使用更加方便些。重点实现了UTF8_to_stringstring_to_UTF82个函数,然后在所有Get和Set函数中调用这2个函数,实现UTF8和UNICODE编码格式转换,细见一下代码: 

 

#pragma once

using namespace std;
#include 
#include   
#include 

#include "tinyxml.h"
#include "tinystr.h"

// 1. 实现各种数据类型转换,特别是std::string 到 unicode CString 转换 

struct CTinyXml
{
public:
	// 将字符串转成基础数据类型,非基础类型需显示定义  
	template  
	bool StringToBaseType(const std::string& str, T& val)  
	{  
		std::istringstream stream;  
		stream.str(str);  
		if (stream >> val)  
		{  
			return true;  
		}  
		return false;  
	}  
	  
	// 将基础数据类型转成字符串,非基础类型需显示定义  
	template  
	bool BaseTypeToString(const T& src, std::string& tar)  
	{  
		std::ostringstream stream;  
		if (stream << src)  
		{  
			tar = stream.str();  
			return true;  
		}  
		return false;  
	}  
	  
	template  
	static bool GetSubNodeValue(TiXmlElement *pElement, const std::string name, T& val)  
	{  
		if (!pElement) return false;  
		TiXmlElement *pTmpElement = pElement->FirstChildElement(name.c_str());  
		return GetNodeValue(pTmpElement, val);  
	}  

	template  
	static bool SetSubNodeValue(TiXmlElement *pElement, const std::string& name, T& val)  
	{  
		if (!pElement) return false;  
		TiXmlElement *pTmpElement = pElement->FirstChildElement(name.c_str());  
		return SetNodeValue(pTmpElement, val);  
	}  
public:
	static	int GetInt(string sText)
		{
			return _tstoi(GetText(sText));
		}
	static	int GetLong(string sText)
		{
			return _tstol(GetText(sText));
		}
	static	float GetFloat(string sText)
		{
			return float(_tstof(GetText(sText)));
		}
	static	double GetDouble(string sText)
		{
			return _tstof(GetText(sText));
		}

	static	CString GetText(string sText)
		{
			string sANS = UTF8_to_string(sText);

			CString strTxt;

			#ifdef _UNICODE
			{
				USES_CONVERSION;
				strTxt = A2W(sANS.c_str ());
			}
			#else
			{
				strTxt = sANS.c_str ();
			}
			#endif

			return strTxt;

		}
	static	string GetText(CString strText)
		{
			string sTxt;

			#ifdef _UNICODE
			{
				USES_CONVERSION;
				sTxt = W2A(strText);

			}
			#else
			{
				sTxt = strText;
			}
			#endif

			return sTxt;

		}

	static	_variant_t c_vt(const char*  pcVarType,const char*  pcVal)
		{
			_variant_t vtVal;
			string sVarType = pcVarType;
			string sVal = pcVal;

			if (sVarType == "VT_BOOL")	// 字符串类型
			{
				vtVal.vt = VT_BOOL;

				if (sVal == "0")
					vtVal.boolVal = VARIANT_FALSE;
				else
					vtVal.boolVal = VARIANT_TRUE;

				return vtVal;
			}
			
			if (sVarType == "VT_I2")
			{
				vtVal.vt = VT_I2;
				vtVal.iVal = GetInt(sVal);
							
				return vtVal;
			}
			
			if (sVarType == "VT_I4")
			{
				vtVal.vt = VT_I4;
				vtVal.intVal = GetLong(sVal);

				return vtVal;
			}
			
			if (sVarType == "VT_R4")
			{
				vtVal.vt = VT_R4;
				vtVal.fltVal = GetFloat(sVal);

				return vtVal;
			}
			
			if (sVarType == "VT_R8")
			{
				vtVal.vt = VT_R8;
				vtVal.dblVal = GetDouble(sVal);

				return vtVal;
			}
			
			if (sVarType == "VT_BSTR")	// 字符串类型
			{
				vtVal.vt = VT_BSTR;
				vtVal.SetString (sVal.c_str ());

				return vtVal;

			}

			return vtVal;
		}

	static	TiXmlElement* GetTiXmlElement(string sName,string sValue)
		{
			string sUtf8_Name = string_to_UTF8(sName);
			string sUtf8_Value = string_to_UTF8(sValue);

			TiXmlElement *pElement	= new TiXmlElement(sUtf8_Name.c_str());
	        TiXmlText *pXmlTxt = new TiXmlText(sUtf8_Value.c_str());

			if (pElement && pXmlTxt)
			{
				pElement->LinkEndChild(pXmlTxt);
				return pElement;
			}

			if (pElement)	delete pElement;
			if (pXmlTxt)	delete pXmlTxt;

			return NULL;
		}

	static	TiXmlElement* GetTiXmlElement(string sName,_variant_t vtValue)
		{
			CString strVal;
			CString strVT;
			switch(vtValue.vt)
			{
			case VT_I2:
				{
					strVal.Format (_T("%d"),vtValue.iVal);
					strVT = _T("VT_I2");
					break;
				}
			case VT_I4:
				{
					strVal.Format(_T("%d"),vtValue.intVal);
					strVT = _T("VT_I4");
					break;
				}
			case VT_R4:
				{
					strVal.Format(_T("%f"),vtValue.fltVal);
					strVT = _T("VT_R4");
					break;
				}
			case VT_R8:
				{
					strVal.Format(_T("%f"),vtValue.dblVal );
					strVT = _T("VT_R8");
					break;
				}
			case VT_BSTR:
				{
					strVal = vtValue.bstrVal;
					strVT = _T("VT_BSTR");
					break;
				}
			case VT_BOOL:
				{
					if (vtValue.boolVal == VARIANT_TRUE )
						strVal = _T("1");
					else 
						strVal = _T("0");

					strVT = _T("VT_BOOL");
					break;
				}
			default:
				return NULL;
				break;
			}

			string sVT = GetText(strVT);
			string sVal= GetText(strVal);

			TiXmlElement *pElement	= GetTiXmlElement(sName,sVal);
			pElement->SetAttribute ("VT",sVT.c_str ());

			return pElement;
		}
	static	TiXmlElement* GetTiXmlElement(string sName,double dValue)
		{
			CString strValue;
			strValue.Format(_T("%lf"),dValue);

			return GetTiXmlElement(sName,GetText(strValue));
		}
	static	TiXmlElement* GetTiXmlElement(string sName,int nValue)
		{
			CString strValue;
			strValue.Format(_T("%d"),nValue);

			return GetTiXmlElement(sName,GetText(strValue));
		}
	static	TiXmlElement* GetTiXmlElement(string sName,long nValue)
		{
			CString strValue;
			strValue.Format(_T("%ld"),nValue);

			return GetTiXmlElement(sName,GetText(strValue));
		}

	// ---->>-- 绑定元素
	static	TiXmlElement *	WriteElement(TiXmlElement *pParent,string sName)
		{
			string sVal;
			TiXmlElement* pElement = GetTiXmlElement(sName,sVal);
			pParent->LinkEndChild(pElement);

			return pElement;
		}
	static	TiXmlElement *	WriteElement(TiXmlElement *pParent,string sName, string sVal)
		{
			TiXmlElement* pElement = GetTiXmlElement(sName,sVal);
			pParent->LinkEndChild(pElement);

			return pElement;
		}
	static	TiXmlElement *	WriteElement(TiXmlElement *pParent,string sName,int& nVal)
		{
			TiXmlElement* pElement = GetTiXmlElement(sName,nVal);
			pParent->LinkEndChild(pElement);

			return pElement;
		}

	static	TiXmlElement *	WriteElement(TiXmlElement *pParent,string sName,UINT& unVal)
		{
			long lVal = (long) unVal;
			TiXmlElement* pElement = GetTiXmlElement(sName,lVal);
			pParent->LinkEndChild(pElement);

			return pElement;
		}

	static	TiXmlElement *	WriteElement(TiXmlElement *pParent,string sName,long& nVal)
		{
			TiXmlElement* pElement = GetTiXmlElement(sName,nVal);
			pParent->LinkEndChild(pElement);

			return pElement;
		}

	static	TiXmlElement *	WriteElement(TiXmlElement *pParent,string sName,ULONG& unVal)
		{
			long lVal = (long) unVal;
			TiXmlElement* pElement = GetTiXmlElement(sName,lVal);
			pParent->LinkEndChild(pElement);

			return pElement;
		}

	static	TiXmlElement *	WriteElement(TiXmlElement *pParent,string sName,float& fVal)
		{
			TiXmlElement* pElement = GetTiXmlElement(sName,(double)fVal);
			pParent->LinkEndChild(pElement);

			return pElement;
		}

	static	TiXmlElement *	WriteElement(TiXmlElement *pParent,string sName,double& dVal)
		{
			TiXmlElement* pElement = GetTiXmlElement(sName,dVal);
			pParent->LinkEndChild(pElement);

			return pElement;
		}

	static	TiXmlElement *	WriteElement(TiXmlElement *pParent,string sName,CString& strVal)
		{
			TiXmlElement* pElement = GetTiXmlElement(sName,GetText(strVal));
			pParent->LinkEndChild(pElement);

			return pElement;
		}
	// ----<<-- 绑定元素

public:
	//c++ string、UTF8相互转换方法
	// 普通sting类型 转UTF-8编码格式字符串
	static	std::string string_to_UTF8(const std::string & sANSI)
	{
		// 1. 转成宽字节的ANSI
		int nwLen = ::MultiByteToWideChar(CP_ACP, 0, sANSI.c_str(), -1, NULL, 0);

		wchar_t * pwBuf = new wchar_t[nwLen + 1];//一定要加1,不然会出现尾巴
		::memset(pwBuf, 0, nwLen * 2 + 2);

		::MultiByteToWideChar(CP_ACP, 0, sANSI.c_str(), sANSI.length(), pwBuf, nwLen);

		int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);

		char * pBuf = new char[nLen + 1];
		::memset(pBuf, 0, nLen + 1);

		// 2. 宽字节的ANSI --> 多字节的UTF8
		::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

		std::string sUTF8(pBuf);

		delete []pwBuf;
		delete []pBuf;

		pwBuf = NULL;
		pBuf = NULL;

		return sUTF8;
	}
	// 



	// UTF-8编码格式字符串  转普通sting类型
	static	std::string UTF8_to_string(const std::string & sUTF8)
	{
		int nwLen = MultiByteToWideChar(CP_UTF8, 0, sUTF8.c_str(), -1, NULL, 0);

		wchar_t * pwBuf = new wchar_t[nwLen + 1];//一定要加1,不然会出现尾巴
		::memset(pwBuf, 0, nwLen * 2 + 2);

		::MultiByteToWideChar(CP_UTF8, 0, sUTF8.c_str(), sUTF8.length(), pwBuf, nwLen);

		int nLen = WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, NULL, NULL, NULL, NULL);

		char * pBuf = new char[nLen + 1];
		::memset(pBuf, 0, nLen + 1);

		::WideCharToMultiByte(CP_ACP, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

		std::string sANSI = pBuf;

		delete []pBuf;
		delete []pwBuf;

		pBuf = NULL;
		pwBuf = NULL;

		return sANSI;
	}

};


 

你可能感兴趣的:(VC)