JSON 和 XML 並沒有一個普遍較好的選擇;每種格式都在它被設計的環境中勝出,而正確的選擇取決於哪個系統會消費你的資料。現代 REST API、JavaScript 服務和行動用戶端傾向於使用 JSON,因為它的語法更簡短、瀏覽器內建了解析器,而且它能直接對應到大多數語言在記憶體中使用的物件和陣列結構。相比之下,XML 仍然是 SOAP 服務、企業訊息匯流排、像 OOXML 和 DocBook 這類文件工作流程、Java 和 .NET 生態系中的設定檔,以及諸如 W3C XML 1.0 規範等標準的契約,其中命名空間、混合內容和處理指令是一級特性。當下游端點、結構描述或監管機構要求使用 XML 時,問題就不再是「哪個比較好」,而是「我要如何在不遺失資訊的情況下將 JSON 轉換成 XML」,而這種轉換沒有單一的標準,所以有文件記載的具型別對應是最安全的做法。JSON To XML 正是將這樣的對應套用在瀏覽器中,將型別保留為屬性,以便接收系統能夠區分數字和數字字串、陣列和物件,以及 null 和空字串。

json or xml which is better
json or xml which is better

JSON vs XML:各個格式勝出的場景

JSON 的語法規範發佈於 ECMAScript 的 JSON.parse 章節,並且鏡像了 JavaScript 的物件字面值:物件是帶有字串鍵的鍵值對映,陣列是有序的列表,而且正好有六種值型別:object、array、string、number、boolean 和 null。解析一份 JSON 文件會得到一棵樹,其葉節點是具型別的值,大多數語言不需要額外標註就能直接消費。

XML 的語法由 W3C 定義,其核心圍繞著元素、屬性、文位元組點、命名空間、處理指令,以及在同一個元素內混合文字和子元素的選項。XML 解析器會產生一種不同的樹,其中值的意義是由元素名稱和文件作者選擇加入的屬性所承載,而不是由解析器決定。

特性JSONXML
原生值型別object、array、string、number、boolean、null元素、屬性、文字;型別來自作者的慣例
順序陣列是有序的;在大多數解析器中,物件保留插入順序子節點的順序具有意義且會被保留
結構描述語言JSON Schema(獨立的草案流程)DTD、XSD 1.0/1.1、Relax NG、Schematron
命名空間無一級特性,透過前綴綁定
註解和處理指令不允許允許
混合文字與元素內容不可能允許
典型生態系適用場景REST API、JavaScript、行動用戶端、設定檔SOAP、企業訊息傳遞、文件格式、Java/.NET 設定

這個表格把權衡變得具體:JSON 較為精簡,並且對應到大多數語言已經使用的資料結構,而 XML 較為豐富,並且對應到需要命名空間、結構描述和人工撰寫標記的生態系。當你掌控兩端並希望最小化額外負擔時,選擇 JSON;當現有的契約、監管機構或合作夥伴強制要求時,選擇 XML。

天真的 JSON 轉 XML 在哪些地方會遺失資訊

JSON 的六種值型別無法一對一對應到 XML。一個走訪 JSON 樹並以鍵名作為元素名輸出的天真轉換器會產生結構良好的標記,但它會悄悄地抹平接收系統所依賴的區別:

  • 數字 vs 數字字串。JSON 值 42 和字串 "42" 帶有不同的意義,但純文字的 XML 元素無法同時容納這兩者。
  • 陣列 vs 物件。兩者都會變成帶有子元素的元素,所以下游解析器無法區分有序列表和無序對映。
  • Null vs 空字串 vs 缺失的鍵。三種不同的 JSON 狀態會塌縮成同一個空元素或缺席的子節點。
  • 空陣列 vs 空物件。若沒有明確的標記,兩者都會呈現為沒有子節點的自閉合元素。
  • 不是合法 XML 名稱的鍵。像 "123-id" 或 "first name" 這樣的鍵不是合法的 XML 元素名稱,將它直接寫成標籤的轉換器會產生無效的標記。

XML 的命名空間、註解、處理指令、CDATA 區段、文件類型宣告以及混合文字與元素內容在 JSON 中根本無法表示,所以任何轉換要不就是忽略它們,要不就是自行發明佔位符。這就是為什麼不存在單一的通用對應:每一次轉換都是一種有文件記載的慣例,而最安全的一種會透過屬性明確保留型別,以便下游程式碼能讀回這些資訊。

具型別對應如何保留保真度

具型別對應為每一個輸出的 XML 元素加上記錄原始 JSON 種類的 type 屬性。陣列會變成標記為 type="array" 的父元素,其每個成員以原始順序渲染為 item 子元素。物件會變成標記為 type="object" 的元素,並保留 JSON.parse 回傳的屬性順序。字串、數字和布林值會成為帶有對應 type 屬性的文字。Null 會成為標記為 type="null" 的自閉合元素。空物件和空陣列會保留其 type 屬性,因此下游讀取器仍然能區分 {} 和 []。

JSON 值XML 表示
"name": "Ada"<name type="string">Ada</name>
"count": 42<count type="number">42</count>
"active": true<active type="boolean">true</active>
"missing": null<missing type="null"/>
"items": [1, 2]<items type="array"><item type="number">1</item><item type="number">2</item></items>
"meta": {}<meta type="object"/>

在這個對應之上有兩條安全規則。首先,只有安全的 XML 名稱會成為元素名稱;接受的模式是以 ASCII 字母或底線開頭,後面接著字母、數字、底線、句點或連字號。以任何大小寫的 xml 開頭的鍵是保留的,不會直接輸出。不符合規則的鍵會成為一個 <item> 元素,其原始鍵會被儲存在一個逸出過的 key 屬性中,因此不會遺失任何資訊。其次,XML 敏感字元會被逸出:在文字中,& 變成 &amp;,小於變成 &lt;,大於變成 &gt;,而雙引號在 key 屬性內也會另外逸出。包含字面文字 <script> 的 JSON 字串會保留為文字,永遠不會被重新解讀為標記。

轉換器還會輸出一個 UTF-8 XML 宣告,讓輸出帶有其他 XML 工具所預期的明確編碼提示。Pretty 模式使用兩格縮排和換行;compact 模式會移除格式化的空白字元,但保留相同的元素、屬性、順序和值。兩種模式都不會重新格式化原始 JSON 的數字詞素:JSON 解析首先會將數字轉換為 JavaScript 的數值,因此諸如尾隨小數零等無意義的詞彙細節並不會被保留。

三步驟將 JSON 轉換為 XML

  1. 貼上有效的 JSON 並輸入一個簡單的 XML 根元素名稱。根名稱必須以 ASCII 字母或底線開頭,後面接著字母、數字、底線、句點或連字號。以任何大小寫的 xml 開頭的名稱是保留的,在輸出前會被拒絕。如果你希望在轉換前取得任何語法錯誤的行號和欄位,可以先用 JSON Validator 驗證 JSON。
  2. 選擇 pretty 或 compact 輸出,然後點選 Convert to XML。Pretty 模式使用兩格縮排以便檢視;compact 模式會移除格式化的空白字元,但保留相同順序的每個元素和屬性。兩種模式會產生相同的邏輯 XML。
  3. 檢查 type 屬性和逸出過的鍵,然後複製 XML 並根據接收系統實際的對應或結構描述來驗證。檢查每個元素上的 type 屬性,以確認數字、布林值和 null 都成功轉換過來,並檢查 <item> 元素上的任何 key 屬性,以確認不安全的原始鍵已被保留。如果你希望並排檢視,可以使用 XML Formatter 格式化結果,並在處理較大的資料集之前先用目標系統解析它。

先轉換一個具代表性的樣本。如果接收系統預期的是廠商特定的 JSON 轉 XML 慣例,例如陣列使用「屬性掛在父元素上」的模式或不同的元素命名規則,那麼具型別對應預設不會符合,你會在推送完整酬載之前先在樣本上發現這個問題。

限制、隱私,以及什麼時候結構描述對應會勝出

轉換完全在瀏覽器內執行。頁面不會上傳、儲存、依 XSD 驗證、或將輸出送到任何端點,所以你貼上的 JSON 會留在你的機器上。處理上限為 500,000 個輸入字元和 64 層的巢狀深度;深度上限是為了避免過度巢狀的輸入耗盡呼叫堆疊,字元上限則是為了限制瀏覽器的工作量。無效的 JSON、無效的根名稱,以及保留的 xml 前綴根名稱會在輸出之前就產生錯誤。

具型別對應也存在明確的不足。它無法表示 XML 命名空間、來自 JSON 鍵的屬性、註解、處理指令、CDATA 區段、文件類型宣告或混合文字與元素內容。它也不保證與廠商不同的 JSON 轉 XML 慣例相容。如果某個 API、結構描述或整合定義了必要的對應,請遵循該契約,而不是假設這個輸出與之相符。當需要來回轉換保真度時,也就是 XML 必須能轉回完全相同的 JSON,請在兩端記錄這個確切的具型別對應,或使用像 XSLT 這樣由結構描述控制的轉換,它能強制規定元素名稱、屬性位置和命名空間前綴。

為了獲得最佳結果,請先驗證 JSON、使用接收系統預期的根名稱、轉換一個具代表性的樣本、用目標系統解析輸出,然後再執行完整的資料集。如果下游消費者完全無法讀取具型別對應,請使用 XSLT 樣式表重新產生 XML,該樣式表會走訪具型別樹並將其重新塑造成廠商預期的形式。

延伸閱讀:從樣本將 JSON 轉換為 Zod 結構描述。

延伸閱讀:如何驗證 JSON 語法並精準定位錯誤。