如何使用UTF-8對(duì)XML文檔進(jìn)行編碼?相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括多倫網(wǎng)站建設(shè)、多倫網(wǎng)站制作、多倫網(wǎng)頁(yè)制作以及多倫網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,多倫網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到多倫省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
Google的Sitemap服務(wù)要求發(fā)布的所有站點(diǎn)地圖必須采用Unicode的UTF-8編碼。Google甚至不允許其他Unicode編碼(如UTF-16),更不用說(shuō)ISO-8859-1這樣的非Unicode編碼了。從技術(shù)上說(shuō),這意味著Google使用的是非標(biāo)準(zhǔn)XML解析器,因?yàn)閄ML Recommendation特別要求“所有XML處理程序必須接受Unicode 3.1的UTF-8和UTF-16編碼”,但這確實(shí)是一個(gè)大問(wèn)題嗎?
每個(gè)人都能使用UTF-8
普遍性是選擇UTF-8的第一個(gè)也是最有說(shuō)服力的理由。它可以處理目前世界上使用的每一種文字。雖然還有少數(shù)空白,但是越來(lái)越不明顯,被逐漸填平了。沒有納入的文字通常也沒有其他任何字符集實(shí)現(xiàn)過(guò),即使有也不能在 XML 中使用。最好的情況下,這些文字通過(guò)字體借用轉(zhuǎn)嫁到 Latin-1 這樣的單字節(jié)字符集。對(duì)這類稀有文字的真正支持可能最先來(lái)自 Unicode,而且可能只有 Unicode 支持它們。
但這僅僅是使用 Unicode 的一個(gè)理由。為什么選擇 UTF-8 而不是 UTF-16 或者其他 Unicode 編碼呢?最直接的原因之一是廣泛的工具支持?;旧纤锌赡苡糜?XML 的主要編輯器都能處理 UTF-8,包括 JEdit、BBEdit、Eclipse、emacs 甚至 Notepad。在 XML 和非 XML 工具中,沒有其他 Unicode 編碼擁有這樣廣泛的工具支持。
對(duì)于其中一些編輯器,如 BBEdit 和 Eclipse,UTF-8 并不是默認(rèn)的字符集?,F(xiàn)在有必要改變默認(rèn)設(shè)置了,所有工具出廠的時(shí)候都應(yīng)該選擇 UTF-8 作為默認(rèn)編碼。除非這樣,否則當(dāng)文件跨越國(guó)界、平臺(tái)和語(yǔ)言傳遞的時(shí)候,我們就會(huì)陷入不能互操作的泥潭。不過(guò)在所有程序都把 UTF-8 作為默認(rèn)編碼之前,自己修改默認(rèn)設(shè)置也很容易。比如在 Eclipse 中,圖 1 所示的“General/Editors”首選項(xiàng)面板允許指定所有文件都使用 UTF-8。您可能注意到 Eclipse 希望默認(rèn)值為 MacRoman,但是如果這樣,當(dāng)把文件傳遞給使用 Microsoft? Windows? 的程序員或者美國(guó)和西歐之外的計(jì)算機(jī)時(shí)將無(wú)法編譯。
圖 1. 改變 Eclipse 的默認(rèn)字符集
當(dāng)然,要讓 UTF-8 其作用,開發(fā)人員交換的文件也都必須使用 UTF-8,但這不成問(wèn)題。與 MacRoman 不同,UTF-8 不局限于少數(shù)文字或者個(gè)別平臺(tái)。任何人都能用 UTF-8。而 MacRoman、Latin-1、SJIS 和其他各種遺留的國(guó)家字符集都不能做到。
UTF-8 在不支持多字節(jié)數(shù)據(jù)的工具中也能正常工作。其他 Unicode 格式如 UTF-16 往往包含很多零字節(jié)。很多工具將這些字節(jié)解釋為文件尾或者其他某種特殊的分界符,造成不希望的、未曾預(yù)料到的、常常是不愉快的結(jié)果。比方說(shuō),如果 UTF-16 數(shù)據(jù)原樣加載到 C 字符串中,字符串可能從第一個(gè) ASCII 字符的第二個(gè)字節(jié)截?cái)?。UTF-8 文件僅在確實(shí)表示 null 的地方包含 null。當(dāng)然,不應(yīng)該選擇這么天真的工具來(lái)處理 XML 文檔。但是,遺留系統(tǒng)中文檔常常在奇怪的地方結(jié)束,沒有人真正認(rèn)識(shí)到或者理解那些字符序列僅僅是舊瓶裝新酒。與 UTF-16 或其他 Unicode 編碼相比,對(duì)于不支持 Unicode 和 XML 的系統(tǒng),UTF-8 更不容易造成問(wèn)題。
專家們的說(shuō)法
XML 是第一個(gè)全面支持 UTF-8 的重要標(biāo)準(zhǔn),但這僅僅是開始。各標(biāo)準(zhǔn)組織都在逐漸推薦 UTF-8。比如,包含非 ASCII 字符的 URL 是長(zhǎng)期困擾 Web 的一個(gè)問(wèn)題。在 PC 機(jī)上工作的包含非 ASCII 字符的 URL 不能用于 Mac,反之亦然。萬(wàn)維網(wǎng)聯(lián)盟(W3C)和 Internet 工程任務(wù)組(IETF)最近同意所有 URL 都必須采用 UTF-8 編碼而不能是其他編碼,從而解決了這一問(wèn)題。
W3C 和 IETF 對(duì)最先、最后還是偶爾使用 UTF-8 變得越來(lái)越強(qiáng)硬。The W3C Character Model for the World Wide Web 1.0: Fundamentals 指出,“如果必須選擇一種字符編碼,則必須是 UTF-8、UTF-16 或 UTF-32。US-ASCII 對(duì) UTF-8 向上兼容(US-ASCII 字符串也是 UTF-8 字符串,參見 [RFC 3629]),因此如果需要與 US-ASCII 保持兼容,UTF-8 非常合適?!笔聦?shí)上,與 US-ASCII 兼容如此重要,幾乎是必需的。W3C 明智地解釋說(shuō),“其他情況下,如對(duì)于 API,UTF-16 或 UTF-32 可能更合適。選擇一種編碼的原因可能包括內(nèi)部處理的效率以及與其他進(jìn)程的互操作性。”
我同意內(nèi)部處理的效率這條理由。比如,Java? 語(yǔ)言中字符串的內(nèi)部表示采用 UTF-16,因此對(duì)字符串的索引更快。不過(guò),Java 代碼永遠(yuǎn)不會(huì)把這種內(nèi)部表示向與它交換數(shù)據(jù)的程序公開。相反,對(duì)于外部數(shù)據(jù)交換,要使用 java.io.Writer,明確地指定字符集。選擇的時(shí)候,強(qiáng)烈推薦 UTF-8。
IETF 甚至更加明確。The IETF Charset Policy [RFC 2277] 指出,在沒有不確定性的語(yǔ)言中:
協(xié)議必須能夠使用 UTF-8 字符集,它由 ISO 10646 編碼集和 UTF-8 字符編碼方法組成,全文參見 [10646] Annex R(修正版 2 中發(fā)布)。
此外,協(xié)議可以規(guī)定如何使用其他 ISO 10646 字符集和字符編碼方案,如 UTF-16,但是不能使用 UTF-8 是對(duì)本策略的違反,這種違反在進(jìn)入或者提升到標(biāo)準(zhǔn)跟蹤過(guò)程時(shí),需要經(jīng)過(guò)變更程序([BCP9] 第 9 節(jié)),并在協(xié)議規(guī)范文檔中提出明確、可靠的理由。
現(xiàn)有的協(xié)議或者從已有數(shù)據(jù)存儲(chǔ)轉(zhuǎn)移數(shù)據(jù)的協(xié)議,可能需要支持其他數(shù)據(jù)集,甚至使用 UTF-8 之外的默認(rèn)編碼。這是允許的,但是必須能夠支持 UTF-8。
要點(diǎn):今后一段時(shí)間,對(duì)遺留協(xié)議和文件的支持可能要求接受 UTF-8 之外的字符集和編碼,但是如果必須如此我會(huì)非常小心。每種新的協(xié)議、應(yīng)用程序和文檔都應(yīng)該使用 UTF-8。
中文、日文和韓文
一種常見的誤解是認(rèn)為 UTF-8 是一種壓縮格式。其實(shí)并非如此。與其他 Unicode 編碼特別是 UTF-16 相比,在 UTF-8 中 ASCII 字符占用的空間只有一半。不過(guò)一些字符的 UTF-8 編碼占用的空間要多出 50%,特別是中文、日文和韓文(CJK)這樣的象形文字。
但即使用 UTF-8 編碼 CJK XML,實(shí)際的大小可能也比 UTF-16 小。比如,中文的 XML 文檔包含大量 ASCII 字符,如 <、>、&、=、"、' 和空格。這些字符的 UTF-8 編碼要比 UTF-16 小。具體的壓縮/膨脹因素因文檔而異,但不論哪種情況,差別都不可能很明顯。
最后,值得一提的是中文和日文這類象形文字,與 Latin、Cyrillic 這類字母文字相比,用字往往更少。由于字符的絕對(duì)量很大,要求每個(gè)字符使用三個(gè)或更多字節(jié)才能完全地表達(dá)這些文字,就是說(shuō),與英文或俄文相比,同樣的詞語(yǔ)或句子,這些語(yǔ)言可以用更少的字表達(dá)。比如,“tree”在日文中用“木”表示(非常像一棵樹)。 用 UTF-8 表示需要三個(gè)字節(jié),而英文單詞“tree”包含四個(gè)字母,需要四個(gè)字節(jié)。日文中的“grove(小樹林)”是“林”(兩棵樹靠在一起)。用 UTF-8 編碼需要三個(gè)字節(jié),而英文單詞“grove”有五個(gè)字母,需要五個(gè)字節(jié)。日文中的“森”(三棵樹)仍然需要三個(gè)字節(jié)。而對(duì)應(yīng)的英文字“forest”需要六個(gè)字節(jié)。
如果確實(shí)需要壓縮,則使用 zip 或 gzip。壓縮后,UTF-8 和 UTF-16 的大小差不多,不論原始大小相差多少。無(wú)論哪種編碼,原始大小越大,壓縮算法去掉的冗余就更多。
健壯性
真正的優(yōu)勢(shì)在于設(shè)計(jì),與以前和以后設(shè)計(jì)的其他任何文本編碼相比,UTF-8 是一種更健壯、更容易解釋的格式。首先,與 UTF-16 相比,UTF-8 沒有 endianness 問(wèn)題。UTF-8 用 Big-endian 和 little-endian 來(lái)表示都是一樣的,因?yàn)?UTF-8 是按 8 位字節(jié)而不是 16 位字定義的。UTF-8 沒有字節(jié)序的不確定性問(wèn)題,后者必須通過(guò)字節(jié)序標(biāo)志或其他試探手段來(lái)解決。
UTF-8 更重要的一個(gè)特征是無(wú)狀態(tài)性。UTF-8 流或序列中的每個(gè)字節(jié)都是明確的。在 UTF-8 中總是可以知道所處的位置,就是說(shuō)給定一個(gè)字節(jié),馬上就能確定它是一個(gè)單字節(jié)字符、雙字節(jié)字符的第一個(gè)字節(jié)、雙字節(jié)字符的第二個(gè)字節(jié),或者三字節(jié)/四字節(jié)字符的第二個(gè)、第三個(gè)或第四個(gè)字節(jié)(當(dāng)然還有其他可能性,但明白這個(gè)意思就行)。在 UTF-16 中,就不能確定字節(jié)“0x41”是不是字母“A”。有時(shí)候是,有時(shí)候不是。必須記錄足夠的狀態(tài)才能確定在流中的位置。如果損失了一個(gè)字節(jié),此后的數(shù)據(jù)就全部無(wú)法用了。在 UTF-8 中,丟失或者破壞的字節(jié)很容易確定,也不會(huì)影響其他數(shù)據(jù)。
UTF-8 并非是萬(wàn)能的。需要隨機(jī)訪問(wèn)文檔特定位置的應(yīng)用程序使用 UCS2 或 UTF-32 這類固定寬度的編碼可能操作起來(lái)更快。(如果考慮到替換對(duì),UTF-16 是一種變長(zhǎng)字符編碼。)但是,XML 處理不屬于這類應(yīng)用程序。XML 規(guī)范特別要求解析器從 XML 文檔的第一個(gè)字節(jié)開始解析直到最后一個(gè)字節(jié),所有現(xiàn)有的解析器都是這樣操作的。更快的隨機(jī)訪問(wèn)對(duì) XML 處理沒有什么幫助,雖然對(duì)于數(shù)據(jù)庫(kù)或其他系統(tǒng)使用不同的編碼這可能是一個(gè)很好的理由,但不適用于 XML。
結(jié)束語(yǔ)
在越來(lái)越國(guó)際化的世界中,語(yǔ)言和政治邊界日漸模糊,依賴于地域的字符集不再適用了。Unicode 是惟一能夠跨越很多地域互操作的字符集。UTF-8 是最好的 Unicode 編碼:
廣泛的工具支持,包括與遺留 ASCII 系統(tǒng)最佳的兼容性。
處理起來(lái)簡(jiǎn)單而高效。
抗訛誤。
平臺(tái)獨(dú)立。
該停止關(guān)于字符集和編碼的爭(zhēng)論了,選擇 UTF-8,結(jié)束紛爭(zhēng)。
看完上述內(nèi)容,你們掌握如何使用UTF-8對(duì)XML文檔進(jìn)行編碼的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!