國際化支持是 XML 的主要優勢之一。遺憾的是,極少有XML格式提供使內容本地化的機制。本技巧文章向您演示了如何開發本地化的 XML 格式。
XML 的主要優勢之一是其對國際化的支持。它的核心字符集 Unicode 提供了機制來支持更具地區普及性的系統 — 如歐洲的 ISO-8859 變體、日本的 Shift-JIS 或中國的 BIG-5。這很好。在最初以狹隘的地域觀點開發了應用程序後,為了進行國際化部署,人們不得不投入大量財力來改寫它們。然而,對於國際化來說,所需的工作遠比對國際化字符集的支持要多。能夠根據一組特定的語言和文化習慣來定制表示信息的方法,這也很重要。這就是所謂的本地化。
一般的本地化
從數據格式本身(這正是使用XML的便利之處)來講,本地化的某些方面(如日期格式和姓名次序)可以用基本的 XML 功能加以解決。一種方法是使用國際標准形式;一個很不錯的示例是日期,對日期最好是使用 ISO 8601 標准(請參閱參考資料)。清單 1 有一個示例:
清單 1. 地區(美國)日期及其本地化後的日期
<?XML version="1.0" encoding="utf-8"?>
<prodUCts>
<!-- US-specific date -->
<product release-date="8/18/2002"/>
<!-- ISO-8601 date -->
<product release-date="2002-08-18"/>
</products>
ISO-8601 日期的一個優勢在於:通常可以在大多數編程語言中將它們作為簡單的字符串進行比較,這和大多數本地化的日期不同。例如,在大多數編程系統中,字符串“8/19/2001”比“8/18/2002”大,即使實際上前面的日期早於後面的。采用 ISO-8601 格式的同等比較 — “2001-08-19”與“2002-08-18”比較 — 則顯示了字符串形式與實際日期比較之間更自然的對應。本地化的軟件可以先使用 ISO-8601 日期,然後以適當的本地化形式實際顯示適合人們使用的字段。大多數編程語言(包括流行的 XSLT 的 EXSLT 擴展庫)都很容易支持這種轉換。
另一個本地化方法是精心地構造數據,以便在本地以適當的方式重新構造它。姓名就是一個的好例子:在某些文化(如中文)中,姓通常在名的前面。清單2顯示了為更好地支持這樣的本地習慣所構造的一個數據示例。
清單 2. 用於本地化的結構化姓名格式的示例
<?XML version="1.0" encoding="utf-8"?>
<signatorIEs>
<!-- The direct approach. -->
<name>Mr. Uche Ogbuji</name>
<!-- Structure to support local conventions -->
<name>
<honorific>Mr.</honorific>
<given>Uche</given>
<family>Ogbuji</family>
</name>
</signatorIEs>
如果采用直接的方法,讀者可能會試圖按習慣推斷姓名的各個部分,但這常常是有風險的。如果姓名的某些部分(如敬語)被省略,那該怎麼辦?那時您能猜出姓名用的是什麼次序嗎?采用第二種方法,您可以根據本地習慣,把顯示給讀者的姓名重新格式化。事實上,如果給出了每一項在可能的先後次序方面的某種提示(如國籍),那麼可以為每個姓名定制姓名的次序。第二種方法顯然增加了一些復雜性和開銷,但是,在選擇各種級別的標記結構以便支持多種習慣時,始終要在實用性與靈活性之間加以權衡。
行內翻譯
另一個常見的本地化問題是如何表示標號、消息、描述以及類似事物的翻譯。XML 1.0 提供了在元素內容和屬性值中使用的語言規范。您可以為每個元素設置語言。清單3是同時具有英語和西班牙語元素的 XML 文檔示例。
清單 3. 其元素具有本地化語言形式的 XML 文檔。
<?XML version="1.0" encoding="utf-8"?>
<menu>
<item id="A" XML:lang="en">Orange juice</item>
<item id="A" XML:lang="es">Jugo de naranja</item>
<item id="B" XML:lang="en">Toast</item>
<item id="B" XML:lang="es">Pan tostada</item>
</menu>
xml:lang 屬性可以具有 RFC 1766 允許的任何值。這意味著可以使用一些值來代表主要的語言指稱(如 en 代表英語,es 代表西班牙語等等)。如果某種語言有多種變體,通過添加流行使用某種變體的區域代號(如 en-US 代表美式英語、en-GB 代表英式英語,或者 es-MX 代表墨西哥西班牙語),您可以更明確地進行定義。請注意,不需要在這裡聲明名稱空間:xml 名稱空間已經隱式地定義在每一個文檔中。還要注意,語言指稱影響相關元素的所有子元素,以及所有其它的子內容。而且,雖然在 XML 規范中特別提到了 XML:lang 屬性,您仍必須在模式中提供它。清單 4 中的 DTD 片段說明了這一點:
清單 4. 支持 XML:lang 的 DTD
<!ATTLIST item XML:lang NMTOKEN #IMPLIED "en">
該聲明添加了對該屬性的支持,並設置了缺省值 en,以免該屬性被忽略。請注意,我沒有添加對 id 屬性的聲明,通常是需要它的。
結束語
本地化所需要做的工作遠不止本文所介紹的。對開發人員而言,通常這更多的是一種通用思想而不是一套一成不變的規則。您必須不斷地問自己:“對於那些我認為理所當然但實際卻隨地區而異的習慣,我的一些代碼和數據會不會無法適應這些習慣的變化呢?”學習各種可能的信息習慣並將所學的構建到代碼中,這是開發人員應具備的一項關鍵技能。XML 提供了能做到這一點的重要基本工具,就看您能否習慣於使用這些工具了。
參考資料
無論您的開發工作以何種方式涉及到了日期,都不妨查閱 Markus Kuhn 的 Summary of the International Standard Date and Time Notation 並給它加上書簽。W3C 對 Date and Time Formats 的說明也值得一看。
請閱讀 RFC 1766 — “Tags for the Identification of Languages”,它定義了 XML:lang 標記中語言項的允許值。
查看 EXSLT 以獲得有用的和被廣泛支持的 XSLT 擴展函數。尤其 dates and times 模塊有用於操作日期的函數。
請訪問國際標准 ISO 8601,它規定了日期和時間的數字表示法。
順便訪問一下 IBM developerWorks Unicode 主題以獲得關於國際化和本地化的更多信息。
請研究一下 IBM WebSphere Studio Application Developer,這是一種易於使用的集成開發環境,用於構建、測試和部署 J2EE 應用程序,包括從 DTD 和模式生成 XML 文檔。