1. 程式人生 > >C++ pugixml 編碼轉換

C++ pugixml 編碼轉換

#include <iostream>
#include <string>
#include <windows.h>

#include "pugixml.hpp"
#include "convert.h"

using std::cout;
using std::cin;
using std::endl;
using std::string;

void createAndSaveFile()
{
	pugi::xml_document doc;
	pugi::xml_node node_dec = doc.prepend_child(pugi::node_declaration);	// xml開頭宣告
	node_dec.append_attribute("version") = "1.0";
	node_dec.append_attribute("encoding") = "utf-8";

	pugi::xml_node node_comm = doc.append_child(pugi::node_comment);	// 註釋
	node_comm.set_value("只是測試");

	pugi::xml_node root_node = doc.append_child("system_parameter");	// 新增子項
	pugi::xml_node sub_node = root_node.append_child("device");		// 子項新增子項

	sub_node.append_attribute("屬性").set_value("Value");		// 子項的子項的屬性及設值

	doc.save_file("F:\\測試.xml");		// 儲存
}

void MbcsToUtf8(string& str,const char* pszMbcs)
{
	WCHAR	*pwchar = nullptr;
	CHAR	*pchar	= nullptr;

	int len = 0;
	int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;	//  確定一個WIN32檔案函式集是否在使用ANSI或OEM字符集內碼表
	len = MultiByteToWideChar(codepage, 0, pszMbcs, -1, NULL, 0);
	pwchar = new WCHAR[len];
	if (pwchar != 0)
	{
		len = MultiByteToWideChar(codepage, 0, pszMbcs, -1, pwchar, len);
		if (len != 0)
		{
			len = WideCharToMultiByte(CP_UTF8, 0, pwchar, -1, 0, 0, 0, 0);
			pchar = new CHAR[len];
			if (pchar != 0)
			{
				len = WideCharToMultiByte(CP_UTF8, 0, pwchar, -1, pchar, len, 0, 0);
				if (len != 0)
				{
					str = pchar;
				}
				delete pchar;
			}
			delete pwchar;
		}
	}
}

void UTF8ToMBCS(std::string& strOut, std::string strUtf8)
{
	strOut.clear();

	WCHAR* lpszW = NULL;
	char* pOut = NULL;
	do
	{
		int nLen = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), strUtf8.length(), NULL, 0);
		try
		{
			lpszW = new WCHAR[nLen];
		}
		catch (...)
		{
			break;
		}

		int nRtn = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), strUtf8.length(), lpszW, nLen);
		if (nRtn != nLen)
		{
			break;
		}

		int MBLen = WideCharToMultiByte(CP_ACP, 0, lpszW, nLen, NULL, 0, NULL, NULL);
		if (MBLen <= 0)
		{
			break;
		}

		pOut = new char[MBLen + 1];
		memset(pOut, 0, MBLen + 1);
		nRtn = WideCharToMultiByte(CP_ACP, 0, lpszW, nLen, pOut, MBLen + 1, NULL, NULL);
		if (nRtn != MBLen)
		{
			break;
		}

		strOut = pOut;

	} while (false);

	if (pOut != NULL)
	{
		delete[] pOut;
	}

	if (lpszW != NULL)
	{
		delete[] lpszW;
	}
}

void openFile()
{
	pugi::xml_document doc;
	pugi::xml_parse_result status = doc.load_file("./測試.xml");	// ansi
	if (status.status != pugi::xml_parse_status::status_ok)
	{
		cout << "xml開啟失敗" << endl;
		return;
	}

	pugi::xml_node tt = doc.child("ConfigData").child("appname");
	string appname = tt.text().as_string();
	cout << "mbcs to utf8 before convert: appname = " << appname << endl;

	string strUtf8;
	UTF8ToMBCS(strUtf8, appname);
	std::cout << "mbcs to utf8 after convert: appname =  " << strUtf8 << std::endl;

//#ifdef WIN32
//	CodeConvert convert;
//	convert.UTF8ToMBCS(appname, appname);
//#else
//	char inbuf[BUFFER_SIZE * 2] = { '\0' }, outbuf[BUFFER_SIZE * 2 + 1] = { '\0' };
//	memcpy(inbuf, strMsg.c_str(), strMsg.length());
//	CodeConvert convert("utf-8", "gb2312");
//	convert.convert(inbuf, strMsg.length(), outbuf, BUFFER_SIZE * 2 + 1);
//	resp.msg = outbuf;
//#endif

	pugi::xml_document docA;
	pugi::xml_parse_result statusA = docA.load_file("./測試ansi.xml");	// ansi
	if (statusA.status != pugi::xml_parse_status::status_ok)
	{
		cout << "xml開啟失敗" << endl;
		return;
	}

	pugi::xml_node ttA = docA.child("ConfigData").child("appname");
	string appnameA = ttA.text().as_string();
	cout << "mbcs to utf8 before convert: appnameA = " << appnameA << endl;

	string strUtf8A;
	MbcsToUtf8(strUtf8A, appnameA.c_str());
	std::cout << "mbcs to utf8 after convert: appnameA =  " << strUtf8A << std::endl;

	UTF8ToMBCS(appnameA, appnameA);
	cout << "mbcs to utf8 convert: appname = " << appnameA << endl;

}

int main(void)
{
	openFile();

	getchar();
	return 0;
}