Google的Sitemap服務要求發布的所有網站地圖必須採用Unicode的UTF-8編碼。 Google甚至不允許其他Unicode編碼(如UTF-16),更不用說ISO-8859-1這樣的非Unicode編碼了。從技術上說,這意味著Google使用的是非標準XML解析器,因為XML Recommendation特別要求“所有XML處理程序必須接受Unicode 3.1的UTF-8和UTF-16編碼”,但這確實是一個大問題嗎?
每個人都能使用UTF-8
普遍性是選擇UTF-8的第一個也是最有說服力的理由。它可以處理目前世界上使用的每一種文字。雖然還有少數空白,但是越來越不明顯,被逐漸填平了。沒有納入的文字通常也沒有其他任何字元集實作過,即使有也不能在 XML 中使用。在最好的情況下,這些文字透過字體借用轉嫁到 Latin-1 這樣的單字節字元集。這類稀有文字的真正支持可能最早來自 Unicode,而且可能只有 Unicode 支持它們。
但這只是使用 Unicode 的一個理由。為什麼選擇 UTF-8 而不是 UTF-16 或其他 Unicode 編碼?最直接的原因之一是廣泛的工具支援。基本上所有可能用於 XML 的主要編輯器都能處理 UTF-8,包括 JEdit、BBEdit、Eclipse、emacs 甚至 Notepad。在 XML 和非 XML 工具中,沒有其他 Unicode 編碼擁有如此廣泛的工具支援。
對於其中一些編輯器,如 BBEdit 和 Eclipse,UTF-8 並不是預設的字元集。現在有必要改變預設設定了,所有工具出廠的時候都應該選擇 UTF-8 作為預設編碼。除非這樣,否則當文件跨越國界、平台和語言傳遞的時候,我們就會陷入不能互通的泥淖。不過在所有程式都把 UTF-8 當作預設編碼之前,先自己修改預設設定也很容易。例如在 Eclipse 中,圖 1 所示的「General/Editors」首選項面板允許指定所有檔案都使用 UTF-8。您可能注意到 Eclipse 希望預設值為 MacRoman,但是如果這樣,當把檔案傳遞給使用 Microsoft® Windows® 的程式設計師或美國和西歐以外的電腦時將無法編譯。
圖1.改變Eclipse 的預設字元集
#當然,要讓UTF-8 其作用,開發人員交換的檔案也都必須使用UTF -8,但這不成問題。與 MacRoman 不同,UTF-8 不限於少數文字或個別平台。任何人都能用 UTF-8。而 MacRoman、Latin-1、SJIS 和其他各種遺留的國家字符集都不能做到。
UTF-8 在不支援多位元組資料的工具中也能正常運作。其他 Unicode 格式如 UTF-16 往往包含許多零位元組。許多工具將這些位元組解釋為文件尾或其他某種特殊的分界符,造成不希望的、未曾預料到的、常常是不愉快的結果。比方說,如果 UTF-16 資料原樣載入到 C 字串中,字串可能會從第一個 ASCII 字元的第二個位元組截斷。 UTF-8 檔案僅在確實表示 null 的地方包含 null。當然,不應該選擇這麼天真的工具來處理 XML 文件。但是,遺留系統中文件常常在奇怪的地方結束,沒有人真正認識到或理解那些字符序列只是舊瓶裝新酒。與 UTF-16 或其他 Unicode 編碼相比,對於不支援 Unicode 和 XML 的系統,UTF-8 更不容易造成問題。
專家們的說法
XML 是第一個全面支持 UTF-8 的重要標準,但這只是開始。各標準組織逐漸推薦 UTF-8。例如,包含非 ASCII 字元的 URL 是長期困擾 Web 的問題。在 PC 機上工作的包含非 ASCII 字元的 URL 不能用於 Mac,反之亦然。萬維網聯盟(W3C)和 Internet 工程任務組(IETF)最近同意所有 URL 都必須採用 UTF-8 編碼而不能是其他編碼,從而解決了這一問題。
W3C 和 IETF 對最先、最後還是偶爾使用 UTF-8 變得越來越強硬。 The W3C Character Model for the World Wide Web 1.0: Fundamentals 指出,「如果必須選擇一種字元編碼,則必須是UTF-8、UTF-16 或UTF-32。US-ASCII 對UTF-8 向上相容(US- ASCII 字串也是UTF-8 字串,請參閱[RFC 3629]),因此如果需要與US-ASCII 保持相容,UTF-8 非常合適。 W3C 明智地解釋說,「其他情況下,如對於API,UTF-16 或UTF-32 可能更合適。選擇一種編碼的原因可能包括內部處理的效率以及與其他進程的互通性。」
我同意內部處理的效率這個理由。例如,Java™ 語言中字串的內部表示採用 UTF-16,因此對字串的索引更快。不過,Java 程式碼永遠不會把這種內部表示向與它交換資料的程式公開。相反,對於外部資料交換,要使用 java.io.Writer,明確地指定字元集。選擇的時候,強烈推薦 UTF-8。
IETF 甚至更明確。 The IETF Charset Policy [RFC 2277] 指出,在沒有不確定性的語言中:
協議必須能夠使用UTF-8 字元集,它由ISO 10646 編碼集和UTF-8 字元編碼方法組成,全文請參閱[10646] Annex R(修正版2 中發布)。
此外,協議可以規定如何使用其他ISO 10646 字符集和字符編碼方案,如UTF-16,但是不能使用UTF-8 是對本策略的違反,這種違反在進入或者提升到標準跟踪流程時,需要經過變更程序([BCP9] 第9 節),並在協議規範文件中提出明確、可靠的理由。
現有的協議或從已有資料儲存轉移資料的協議,可能需要支援其他資料集,甚至使用 UTF-8 以外的預設編碼。這是允許的,但是必須能夠支援 UTF-8。
重點:今後一段時間,對遺留協定和文件的支援可能要求接受 UTF-8 以外的字元集和編碼,但是如果必須如此我會非常小心。每種新的協定、應用程式和文件都應該使用 UTF-8。
中文、日文和韓文
常見的誤解是認為 UTF-8 是一種壓縮格式。其實並非如此。與其他 Unicode 編碼特別是 UTF-16 相比,在 UTF-8 中 ASCII 字元佔用的空間只有一半。不過有些字符的 UTF-8 編碼佔用的空間要多出 50%,特別是中文、日文和韓文(CJK)這樣的象形文字。
但即使用 UTF-8 編碼 CJK XML,實際的大小也可能比 UTF-16 小。例如,中文的XML 文件包含大量ASCII 字符,如、&、=、"、' 和空格。這些字符的UTF-8 編碼要比UTF-16 小。具體的壓縮/膨脹因素因文檔而異,但不論哪種情況,差別都不可能很明顯。往往更少。可以用更少的字來表達。 ,需要四個位元組。字母,需要五個位元組。 ,則使用
zip或gzip。更多。 。定義的。
UTF-8 更重要的一個特徵是無狀態性。 UTF-8 流或序列中的每個位元組都是明確的。在UTF-8 中總是可以知道所處的位置,就是說給定一個字節,馬上就能確定它是一個單字節字符、雙字節字符的第一個字節、雙字節字符的第二個字節,或三字節/四字節字元的第二個、第三個或第四個位元組(當然還有其他可能性,但明白這個意思就行)。在 UTF-16 中,就不能確定位元組「0x41」是不是字母「A」。有時候是,有時候不是。必須記錄足夠的狀態才能確定在流中的位置。如果損失了一個字節,此後的資料就全部無法用了。在 UTF-8 中,遺失或破壞的位元組很容易確定,也不會影響其他資料。
UTF-8 並非是萬能的。需要隨機存取文件特定位置的應用程式使用 UCS2 或 UTF-32 這類固定寬度的編碼可能操作得更快。 (如果考慮到替換對,UTF-16 是一種變長字元編碼。)但是,XML 處理不屬於這類應用程式。 XML 規格特別要求解析器從 XML 文件的第一個位元組開始解析直到最後一個位元組,所有現有的解析器都是這樣操作的。更快的隨機存取對 XML 處理沒有什麼幫助,雖然對於資料庫或其他系統使用不同的編碼這可能是一個很好的理由,但不適用於 XML。
結束語
在越來越國際化的世界中,語言和政治邊界日漸模糊,依賴地域的字元集不再適用了。 Unicode 是惟一能夠跨越許多地理互通的字元集。 UTF-8 是最好的 Unicode 編碼:
廣泛的工具支持,包括與遺留 ASCII 系統最佳的兼容性。
處理起來簡單又有效率。
抗謳誤。
平台獨立。
該停止關於字元集和編碼的爭論了,選擇 UTF-8,結束紛爭。
以上是詳細介紹使用UTF-8對XML文件進行編碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!