tinyxml定義的類或函數中涉及的字元大都是char,字元串指針也是char*或const char*,看一下面幾個函數:
const char* TiXmlElement::Attribute( const char* name ) const
int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
...
這樣在你的應用程式中擷取的字元串就是const char*類型,如果你的XML文檔指定是UTF-8編碼(注意儲存的時候也是以UTF-8編碼方式儲存的),例如:
<?xml version="1.0" encoding="UTF-8">
<root>
<item>中文字元</item>
</root>
而你的應用程式可能是UNICODE,也可能是多位元組,那麼在應用程式中會這樣讀xml文檔:
TiXmlDocument doc("UTF8test.xml");
doc.LoadFile(TIXML_DEFAULT_ENCODING);//TIXML_DEFAULT_ENCODING指明按照UTF-8編碼方式讀取xml文檔
TiXmlElement* root = doc.RootElement();
TiXmlNode* node = root->FirstChild("item");
TiXmlElement* element = node->ToElement();
const char* text = element->GetText();
要注意此時的text,它指向的記憶體儲存的資料是一個char類型的字元,以0結尾,如果你将其直接輸出得到的将是亂碼,它的内容如下:
e4 b8 ad e6 96 87 e5 ad 97 e7 ac a6 00
這一串資料是儲存在檔案中的UTF-8編碼,它們是多位元組字元.
将其轉換為寬字元(寬字元的意思是:UNICODE 字元在記憶體中是以"UNICODE字元集中的序号"存在).
WCHAR wtext[MAX_PATH] = {0};
MultiByteToWideChar(CP_UTF8, 0, text, -1, wtext, MAX_PATH);
再看看wtext中的内容: 2d 4e 87 65 57 5b 26 7b 00 00
這是在記憶體中存放的UTF-8字元編碼的序号(UNICODE字元字元記憶體中存放的是其序号而不是其編碼).
再将wtext轉換為多字元(CP_ACP方式編碼) :
char sztext[MAX_PATH] = {0};
WideCharToMultiByte(CP_ACP, 0, wtext, -1, sztext, MAX_PATH, NULL, NULL);
再看看sztext中的内容: d6 d0 ce c4 d7 d6 b7 fb 00
可以看到,text,wtext,sztext指向記憶體中的資料并不相同.
還有一點,如果text中的内容是ASII嗎,你就不用轉換了,可以直接拿來使用.
在記憶體中動态生成XML檔案時,仍然是ANSI編碼方式,如下面代碼.
TiXmlDocument* m_pTinXMLDoc = new TiXmlDocument;
TiXmlDeclaration* pdecl = new TiXmlDeclaration("1.0", "UTF-8", "yes");
m_pTinXMLDoc->LinkEndChild(pdecl); // <?xml version="1.0" encoding="UTF-8"?>
// <TransmitInfo datetime="2012-10-10 19:10:23" cmd="1" category="">
TiXmlElement* pEleRoot = new TiXmlElement("RootNode");
pEleRoot->SetAttribute("id", "這是中文");
TiXmlElement* pNode = new TiXmlElement("中文标簽");
pNode->SetAttribute("中文屬性", "屬性值");
pEleRoot->LinkEndChild(pNode);
m_pTinXMLDoc->LinkEndChild(pEleRoot);
m_pTinXMLDoc->SaveFile("e:\\testansi.xml");
檔案内容如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<RootNode id="這是中文">
<中文标簽 中文屬性="屬性值" />
</RootNode>
上面代碼需要注意一個調用:new TiXmlDeclaration("1.0", "UTF-8", "yes");參數"UTF-8"不是設定記憶體中xml檔案的編碼方式,而僅僅是這隻檔案頭encoding的屬性,跟檔案實際編碼方式無關.不過這樣做還是意義的,可以擷取檔案内容字元串,然後轉換為utf-8格式,在網絡上傳輸.如下代碼:
TiXmlPrinter printer;
m_pTinXMLDoc->Accept(&printer);
int nxmlBytes = printer.Size();
const char* xmlcstr = printer.CStr();
ASSERT(strlen(xmlcstr)==nxmlBytes && nxmlBytes<nLen);
//将xmlcstr轉換為utf-8
//...略.
轉換之後,encoding=UTF-8真正表示檔案的編碼格式.
另外,調用SaveFile儲存到本地時,仍然是以ANSI字元格式儲存到本地.
是以,實際上xml檔案頭中的屬性encoding=UTF-8,但檔案未必是UTF-8編碼方式.
本文轉自jetyi51CTO部落格,原文連結: http://blog.51cto.com/jetyi/761708,如需轉載請自行聯系原作者