跳至內容

JSON、YAML 與 XML 比較:該用哪種資料格式

JSON、YAML、XML 並列比較:同一筆資料的三種寫法、型別支援、語法特性,以及實務上的選擇建議。

JSON、YAML、XML 都是把結構化資料表達成文字的格式,但語法、生態系與 取捨差異夠大,選錯了會帶來長期成本。本文並列比較三者,並給出明確的 選擇規則。

三種格式概覽

屬性JSONYAMLXML
主要用途API、傳輸格式設定檔、IaC、CI 流程文件、舊系統
註解不支援支援(#支援(<!-- -->
SchemaJSON Schema(外掛)可用 JSON SchemaXSD、RELAX NG、DTD
錨點與參照不支援支援(&*有限(DTD)
屬性與內容區分不區分不區分區分(attribute)
解析複雜度高(縮排、隱式型別)高(namespace、DTD)
人類可寫性最佳最差
檔案大小最小最大

同一筆資料的三種寫法

JSON 中的使用者紀錄:

{
  "id": 42,
  "name": "Ada Lovelace",
  "active": true,
  "tags": ["admin", "founder"]
}

同一筆資料寫成 YAML:

id: 42
name: Ada Lovelace
active: true
tags:
  - admin
  - founder

寫成 XML:

<user id="42" active="true">
  <name>Ada Lovelace</name>
  <tags>
    <tag>admin</tag>
    <tag>founder</tag>
  </tags>
</user>

注意 XML 有一個 JSON 與 YAML 沒有的選擇:idactive 可以是元素的 屬性,也可以是子元素。這份彈性是為何 XML 的對應方式各家專案都不同。

資料型別

  • JSON 有六種型別:string、number、boolean、null、object、array。沒有日期、沒有二進位。
  • YAML 包含 JSON 全部型別,外加時間戳記,並有隱式型別——1.01yesnoonoffnull~ 都有魔法。著名的 Norway problem:國碼 NO 在沒加引號時會變成布林值 false
  • XML 基底規格沒有型別——一切都是文字。XSD 可加上型別系統,但屬於另一份文件,企業以外鮮少使用。

對於型別需求高但又不想處理 schema 的情境,JSON 的簡單性勝出。需要完整 型別系統時,再加上 JSON Schema、OpenAPI 或 XSD。

註解、錨點與命名空間

JSON 三者皆無。YAML 兩者皆有:

defaults: &defaults
  region: us-east-1
  timeout: 30

prod:
  <<: *defaults
  bucket: prod-bucket

staging:
  <<: *defaults
  bucket: staging-bucket

錨點是手動編輯設定檔的殺手級功能;這就是 YAML 為何成為 Kubernetes、GitHub Actions、Ansible 設定的主流選擇。

XML 的優勢是 namespace 與「文件加混合內容」模型——適合 SOAP、SVG、 文書檔等需要文字與標記交錯的情境,但對純資料記錄則過於沉重。

大小、解析速度與安全性

JSON 解析器速度極快——V8 的 JSON.parse 是手寫組語。YAML 解析器 必須實作大得多的文法,自然較慢;某些病態文件曾造成 CVE(billion laughs 攻擊在 YAML 與 XML 可行,在 JSON 不行)。

XML 的外部實體(XXE)長期是資安隱患。若解析來自不可信來源的 XML, 請明確關閉外部實體解析。

純檔案大小方面,同一份資料下 YAML 通常最小、JSON 居中、XML 最大, 有時相差兩倍。

選擇建議

  • HTTP API、傳輸格式——JSON。普遍支援、解析快、無意外。
  • 人類手動編輯的設定檔——YAML。註解與錨點物超所值。
  • CI/CD 流水線定義——YAML,因為生態系(GitHub Actions、GitLab CI、CircleCI)已標準化於此。
  • 文件導向、含混合內容的資料——XML。例如 DOCX、SVG、RSS、SOAP。JSON 無法乾淨表達 Hello <b>world</b>!
  • 新企業整合專案——JSON 搭配 OpenAPI。除非合作方強制,否則不再選 XML/SOAP。
  • 高流量機器對機器——JSON,或改用 Protocol Buffers、MessagePack 等二進位格式。

三者互轉

實務上你常需要把資料從一種格式轉到另一種:把 YAML 設定塞進 JSON API 請求、把舊夥伴的 XML 轉回 JSON。型別簡單時這些轉換大多是機械式的:

有損的邊界包括:YAML 錨點轉換後會展平、XML 屬性與元素區分會塌陷、 XML 中「陣列 vs 單一元素」本質模糊。請明確記錄你的轉換約定。

延伸閱讀