XML 常被形容成過時,這很奇怪,因為你今天幾乎肯定打開過好幾個 XML 檔而沒有察覺。它確實輸掉了「在程式之間傳資料」那場爭論——JSON 贏得很徹底。其餘的它都守住了。
XML 是 Extensible Markup Language(可延伸標記語言)的縮寫。它長得像 HTML,但有一個關鍵差別:HTML 的標籤是固定的、已經幫你定義好的,而在 XML 裡標籤是你自己發明的。
<book>
<title>西遊記</title>
<year>1592</year>
</book>
沒有任何東西事先定義了 <book>。這個格式給你文法——標籤、巢狀、屬性——而詞彙由你依資料所需提供。
.docx 是一個裝滿 XML 的 zip 封存檔;文字、格式和結構全部都是裡面的 XML 檔。那不是一份遺產清單。那是 XML 被證明選對了的地方。
這是分界的核心,而且一個例子就能解釋整個局面。
想想一個中間帶強調的句子:那隻敏捷的棕狐,其中只有「敏捷」是斜體。在 XML 裡這很自然:
<p>那隻<em>敏捷的</em>棕狐</p>
文字和標記交錯在一起——XML 把這叫做混合內容。那個元素裡裝了一些文字,然後一個元素,然後又是文字。
JSON 沒有任何辦法表達這個。它的值只能是字串、數字、清單或物件;它沒有「文字,而且在特定位置嵌著東西」這個概念。要在 JSON 裡表示那個句子,得發明一套約定——一個片段的陣列,每個片段標上它的樣式——然後所有人都得同意你的發明。
文件就是由混合內容組成的。真實文件裡幾乎每一個句子裡面都有被標記起來的東西。這就是為什麼文書處理軟體、電子書和頁面排版是 XML,也是為什麼它們會繼續是 XML。
資料不是那樣。價格是一個數字、名稱是一個字串、訂單有一串品項。JSON 完美貼合那個,而 XML 只是多加了標點。
<book id="42">——附在元素上而不是放在它裡面的中繼資料。<!-- 像這樣 -->。JSON 完全沒有,這在設定檔裡是真實的不便。XML 比 HTML 嚴格得多,也遠沒那麼寬容:
<br> 無效;<br/> 才對。<Book> 和 <book> 是不同的元素。然後是那個造成的壞 XML 比其他全部加起來還多的:& 符號。
有五個保留字元,而 & 是危險的那個,因為它在網址裡不斷出現。一個帶參數的網址在參數之間含有 &,而原封不動貼進 XML 會立刻讓檔案失效。它必須寫成 &。
這就是一份 sitemap 或 RSS 訂閱源被驗證器拒絕的常見原因:某個連結裡一個沒跳脫的 & 符號。另外四個是 <、>、" 和 ',分別寫成 <、>、" 和 '。
對一整塊充滿這類字元的文字,<![CDATA[ ... ]]> 標出一個剖析器應該照字面處理的區域——那是把 HTML 放進 RSS 訂閱源的標準做法。
不像 CSV,XML 把編碼問題好好解決了。第一行就宣告它:
<?xml version="1.0" encoding="UTF-8"?>
檔案自己說明它是什麼,所以沒有東西需要猜,而中文或日文內容在系統之間搬移也活得下來。這是一件小事,但它消掉了一整類的失敗。
XML 很囉嗦——每個值都被一個開標籤和一個閉標籤包起來,往往還掛著命名空間。對一個每秒被呼叫一千次的 API 來說那是純粹的浪費,而 JSON 是正確答案。
但對一份必須在三十年後還讀得懂、必須能對照一份公布的標準被驗證、而且必須被兩個從沒講過話的組織完全一致地解讀的文件來說,那個囉嗦是在做事。檔案自我描述、綱要定義什麼是合法的,而沒有任何東西依賴一個從來沒被寫下來的共同假設。
這就是值得記住的分界:JSON 給流動中的資料,XML 給必須存續的文件。
& 就會毀掉檔案——寫成 &,網址裡尤其要注意