封裝tinyxml實現對UTF8和UNICODE編碼格式轉換
阿新 • • 發佈:2019-02-04
tinyxml對儲存xml非常方便,但儲存的格式卻不是UTF8,導致實際使用中遇到讀取問題。
為了方便使用,藉助對C++ 儲存檔案為UTF8編碼格式學習,實現對tinyxml的資料轉換做了一些封裝,使使用更加方便些。重點實現了UTF8_to_string和string_to_UTF82個函式,然後在所有Get和Set函式中呼叫這2個函式,實現UTF8和UNICODE編碼格式轉換,詳細見一下程式碼:
#pragma once using namespace std; #include <string> #include <sstream> #include <COMUTIL.H> #include "tinyxml.h" #include "tinystr.h" // 1. 實現各種資料型別轉換,特別是std::string 到 unicode CString 轉換 struct CTinyXml { public: // 將字串轉成基礎資料型別,非基礎型別需顯示定義 template<class T> bool StringToBaseType(const std::string& str, T& val) { std::istringstream stream; stream.str(str); if (stream >> val) { return true; } return false; } // 將基礎資料型別轉成字串,非基礎型別需顯示定義 template<class T> bool BaseTypeToString(const T& src, std::string& tar) { std::ostringstream stream; if (stream << src) { tar = stream.str(); return true; } return false; } template<class T> 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<class T> 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; } };