知識 · 文字、資料與資安
JSON、YAML、XML 比較:該用哪種格式?
簡答
JSON、YAML 和 XML 都是描述結構化資料的文字格式。JSON 精簡又嚴格,有六種值型別,是 Web API 的主流。YAML 以縮排表示結構、允許註解,常用於設定檔。XML 使用標籤和屬性,支援命名空間與正式的 Schema,在文件、企業系統和訂閱源中仍很常見。三者都能表示相同的巢狀資料。
開啟JSON 格式化同一筆資料,三種格式
一位有名稱、啟用旗標和兩個角色的使用者,在各格式中長這樣:
| 格式 | 範例 |
|---|---|
| JSON | {"name": "Ana", "active": true, "roles": ["admin", "editor"]} |
| YAML | name: Ana / active: true / roles: [admin, editor](每行一個鍵) |
| XML | <user active="true"><name>Ana</name><role>admin</role><role>editor</role></user> |
JSON 和 YAML 可直接對應到多數程式語言中的物件、清單和純量。XML 描述的是一棵元素樹,對應到物件的方式只是慣例:這裡的啟用旗標可以是屬性,也可以是子元素,而 XML 本身也沒有表明這個值是布林值,而不是文字 true。
並排比較
| JSON | YAML | XML | |
|---|---|---|---|
| 規格 | RFC 8259、ECMA-404 | YAML 1.2.2(2021) | W3C XML 1.0 第五版 |
| 結構 | 大括號與中括號 | 縮排 | 開始與結束標籤 |
| 註解 | 不允許 | # comment | <!-- comment --> |
| 內建型別 | 物件、陣列、字串、數字、布林、null | 對應表、序列、會被解析成各種型別的純量 | 只有文字,除非 Schema 指定型別 |
| Schema 語言 | JSON Schema | 通常用 JSON Schema | XSD、DTD、RELAX NG |
| 額外功能 | 無 | 錨點與別名、單一檔案含多份文件 | 屬性、命名空間、混合內容 |
| 常見用途 | Web API、瀏覽器資料、記錄檔 | 設定檔:Kubernetes、CI 管線、Docker Compose | Office 檔案、SVG、RSS、SOAP、Android 版面配置 |
JSON:嚴格且可預期
JSON 的文法小到一頁就寫得完,所以各種語言的剖析器對它的解讀都一致。但這份嚴格也造成最常見的錯誤:
- 鍵和字串必須用雙引號;單引號是不合法的。
- 物件或陣列的最後一個項目後面不能有逗號。
- 不能寫註解,所以用 JSON 寫的設定檔無法自我說明。JSONC、JSON5 等變體加入了註解,但它們不是標準 JSON。
- RFC 8259 要求系統之間交換的 JSON 必須使用 UTF-8。
文法本身對數字大小沒有限制,但 RFC 8259 指出多數軟體使用 IEEE 754 倍精度浮點數。在 JavaScript 中,大於 9007199254740992(2^53)的整數會失去精確度,所以較大的 ID 以字串傳送比較安全。
YAML:好讀,但暗藏陷阱
YAML 的設計目標是方便人閱讀和編輯,而 YAML 1.2 幾乎是 JSON 的超集,所以多數 JSON 檔也是合法的 YAML。不過它的彈性是有代價的:
- 縮排就是結構。一個空格放錯,巢狀層級就變了,而且不能用 Tab 縮排。
- 沒加引號的值會被猜測型別。依照許多剖析器仍在使用的 YAML 1.1 規則,
no、off和yes會變成布林值,於是國碼NO變成了false。YAML 1.2 的 core schema 只把true和false當成布林值,但請確認你的剖析器實作的是哪個版本。 - 像
1.10這樣的值可能變成數字1.1,012可能變成八進位數字。只是長得像數字的字串,例如版本號和郵遞區號,請加上引號。
XML:冗長,但專為文件而生
用來表示單純資料時,XML 比 JSON 笨重,但它能處理其他兩者做不到的事:混合內容(文字中夾帶行內標記,例如 <p>Hello <b>world</b></p>)、讓不同來源的詞彙共存於同一檔案的命名空間,以及透過 XSD 進行的成熟驗證。DOCX、XLSX、SVG 和 RSS 等格式底層都是 XML。
XML 轉 JSON 本質上就會有所遺失。屬性、元素順序、重複元素和混合內容在 JSON 中都沒有唯一的對應方式,所以轉換工具會自訂慣例,例如屬性加上 @ 前綴,或強制把重複元素轉成陣列。
常見問題
YAML 是 JSON 的超集嗎?
YAML 1.2 經過修訂後幾乎是 JSON 的嚴格超集,所以幾乎所有 JSON 文件都能當成 YAML 剖析。少數邊界情況不同,而 YAML 1.1 剖析器的相容性較差。
JSON 為什麼不能寫註解?
JSON 的作者刻意拿掉註解,以免有人用註解夾帶剖析指令而破壞互通性。需要在設定檔寫註解的工具會改用 JSONC、JSON5 或 YAML。
JSON 和 XML 哪個剖析得比較快?
同樣的資料,JSON 通常更快也更小,因為文法較簡單,沒有結束標籤、屬性或命名空間。差距主要在資料量很大時才明顯。
YAML 轉 JSON 會遺失資料嗎?
資料本身會保留,但註解、錨點和鍵的格式不會,因為 JSON 沒有地方放它們。JSON 轉 YAML 則不會遺失任何東西。