TinyXML是個(gè)好東西,這個(gè)不用我多說(shuō)了,我用它做過(guò)好幾個(gè)項(xiàng)目,但這幾個(gè)項(xiàng)目都只是從xml文件中獲取信息,沒(méi)有涉及到寫(xiě)文件,最近需要生成xml的配置文件,才注意到這個(gè)問(wèn)題,那就是TinyXML似乎不能保存文件為UTF-8格式。
我用UltraEdit打開(kāi)生成的xml文件,UltraEdit把它識(shí)別為ASCII格式的文本文件,而通過(guò)二進(jìn)制查看,也確實(shí)如此,我看了下幫助文檔,也沒(méi)具體提及到這個(gè)問(wèn)題。但后來(lái)我仔細(xì)整理了一下思路后,發(fā)覺(jué)這個(gè)其實(shí)不算什么問(wèn)題,分析如下。
文檔上就說(shuō)明了,TinyXML是完全支持UTF-8的,可以嘗試load一個(gè)UTF-8格式的xml文件,完全沒(méi)有問(wèn)題,那現(xiàn)在問(wèn)題是load了一個(gè)UTF-8文件后,文件中的字符串,在TiXmlDocument對(duì)象中,到底是什么格式?TinyXML在load它之后會(huì)不會(huì)直接把UTF-8格式轉(zhuǎn)為Unicode格式?——不會(huì),為什么?因?yàn)門(mén)inyXML在編寫(xiě)的時(shí)候是把自己定位為一個(gè)比較單純的C++ Lib,它沒(méi)有使用任何Windows相關(guān)的API,包括很重要的兩個(gè)編碼轉(zhuǎn)換函數(shù)WideCharToMultiByte和MultiByteToWideChar,它都沒(méi)用,對(duì)不同平臺(tái),編碼轉(zhuǎn)換函數(shù)可能是不同的,因此TinyXML不會(huì)畫(huà)蛇添足地提供這個(gè)轉(zhuǎn)換,也就是說(shuō),如果你的xml文件(UTF-8格式)中如果有中文的話,用TinyXML加載進(jìn)來(lái)之后,依舊是UTF-8的,不經(jīng)過(guò)轉(zhuǎn)換直接print出來(lái)的話,就是亂碼了,所以要經(jīng)過(guò)一個(gè)UTF-8到Unicode的轉(zhuǎn)換,轉(zhuǎn)換代碼我這里就不寫(xiě)了。再說(shuō)一下,TinyXML聲稱對(duì)UTF-8的支持表示它認(rèn)識(shí)UTF-8的xml文件,但并不表示它自動(dòng)對(duì)UTF-8的文本進(jìn)行轉(zhuǎn)換。
好,再回到保存的問(wèn)題上,其實(shí)你差不多想到了,應(yīng)該怎么做,因?yàn)檎麄€(gè)TinyXML其實(shí)并不計(jì)較內(nèi)存中的文本究竟是什么內(nèi)容,它都可以把文本當(dāng)做是UTF-8(當(dāng)然了,實(shí)際上把文本轉(zhuǎn)為UTF-8然后交給TinyXML的工作是我們的程序去完成),那我們可不可以說(shuō)保存的xml文件其實(shí)就已經(jīng)是UTF-8格式的?——答案是肯定的。而UTF-8的格式標(biāo)志其實(shí)就是文件頭的三個(gè)字節(jié):0xEF,0xBB,0xBF。有了這個(gè)頭,用UltraEdit打開(kāi)這個(gè)xml,UltraEdit就把它認(rèn)為是一個(gè)UTF-8的文本文件了。
這個(gè)改動(dòng)非常簡(jiǎn)單,稍微瀏覽下TinyXML的代碼就知道怎么改了,我下載的TinyXML是2.6.1版本的(我沒(méi)記錯(cuò)的話),在tinyxml.cpp文件中搜索“useMicrosoftBOM”,把“useMicrosoftBOM = false;”這個(gè)語(yǔ)句改為“useMicrosoftBOM = true;”就可以了,好像一共才三處地方,十分簡(jiǎn)單,代碼一看就懂,不多說(shuō)了。