tinyxml对存储xml非常方便,但存储的格式却不是UTF8,导致实际使用中遇到读取问题。
为了方便使用,借助对C++ 保存文件为UTF8编码格式学习,实现对tinyxml的数据转换做了一些封装,使使用更加方便些。重点实现了UTF8_to_string和string_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;
}
};