← 全部文章

JSON 轉 XML:根元素、陣列與屬性對應

把 JSON 轉成 XML:選根元素、把 @ 前綴鍵對應到屬性、把陣列轉成重複元素、處理轉義 —— 在 JS、Python 與線上完成。

把 JSON 轉換為 XML 是一個有損對映的反向操作,這意味著你必須做出 JSON 從不強迫你做的選擇:根元素是什麼?這個鍵應該變成屬性還是子元素?JSON 陣列怎麼變成重複的 XML 標籤?本指南涵蓋 JSON 轉 XML 的慣例 —— 根元素、陣列、屬性與跳脫 —— 在 JavaScript、Python 與瀏覽器中。

選擇根元素

XML 要求有且僅有一個根元素;JSON 沒有這條規則。所以第一個決定就是要用什麼把所有內容包起來。如果你的 JSON 是只有一個頂層鍵的物件,那個鍵就是天然的根:

{ "note": { "to": "Ada", "from": "Bob" } }

<note>
  <to>Ada</to>
  <from>Bob</from>
</note>

如果 JSON 有多個頂層鍵(或是陣列),就沒有單一的根,轉換器會把所有內容包在一個合成的元素裡,例如 <root>

{ "to": "Ada", "from": "Bob" }

<root>
  <to>Ada</to>
  <from>Bob</from>
</root>

@-前綴鍵變屬性

為了與 XML 轉 JSON 的慣例能完整往返,以 @ 開頭的鍵會被輸出為屬性而不是子元素,而 #text 鍵則成為該元素的文字內容:

{
  "price": { "@currency": "USD", "#text": "9.99" }
}

<price currency="USD">9.99</price>

如果不使用這個慣例,每個值都會變成子元素 —— 也是合法的,只是更囉嗦。這套 @#text 慣例,才讓 XML → JSON → XML 能做到無損往返。

陣列變成重複的元素

JSON 陣列不會變成一個有多個值的單一元素 —— 而是變成同名元素的多次重複,因為這就是 XML 表示列表的方式:

{ "tags": { "tag": ["a", "b", "c"] } }

<tags>
  <tag>a</tag>
  <tag>b</tag>
  <tag>c</tag>
</tags>

一個微妙的後果是:頂層的物件陣列不能當作根(那會產生多個根元素),所以必須包起來 —— 常見作法是用 <root> 包住重複的 <item> 元素。

沒有清晰對映的值

  • 布林與數字 —— XML 沒有型別,所以 true42 都寫為文字 true42
  • null —— 通常是空/自閉合的元素:<middleName/>
  • 不是合法元素名的鍵 —— 名字不能以數字開頭或含空白。"1st place" 不是合法的標籤,必須先做清洗,否則會得到不合法的 XML。

跳脫與宣告

文字與屬性值必須跳脫 &<>(屬性裡還有 ")。轉換器還應在前面加上 XML 宣告,讓輸出成為完整文件:

<?xml version="1.0" encoding="UTF-8"?>
<message>B &amp; C are &lt; D</message>

對應 XSD 或產出 xmlns

如果你的下游會依一份 XSD(XML Schema)來校驗 XML,轉換除了「鍵→元素」的對映之外,還需要做幾件額外的事:

  • 元素順序很重要。 XML 的元素屬性(依規範)是無序的,但子元素是有序的,多數 XSD 透過 xsd:sequence 強制這一順序。請依 Schema 期望的順序輸出子元素,而不是依物件鍵的走訪順序,否則校驗會失敗。
  • 命名空間對映。xmlns 宣告以 @xmlns 屬性的形式重建在根上,並把帶前綴的名字反映回 XML("soap:Envelope"<soap:Envelope>)。遺失命名空間的轉換器會產出無法通過任何依賴命名空間的 XSD 校驗的 XML。
  • 型別感知的值。 XML 沒有原生型別,所以帶 xsd:intxsd:date 的 XSD 只是檢查文字內容是否符合。請把 JSON 值格式化為 XSD 模式期望的文字(ISO 日期、整數字串等)。

用程式碼把 JSON 轉為 XML

// JavaScript —— 一個小型遞迴建構器,或者函式庫:
import { XMLBuilder } from 'fast-xml-parser';
const builder = new XMLBuilder({ ignoreAttributes: false, attributeNamePrefix: '@' });
const xml = builder.build(jsonObject);

# Python —— dicttoxml,或以 xml.etree.ElementTree 自建
from dicttoxml import dicttoxml
xml_bytes = dicttoxml({"note": {"to": "Ada"}}, attr_type=False)

線上把 JSON 轉為 XML

把 JSON 貼進 JSON ⇄ XML 轉換器 並點擊 To XML。它會挑選一個合理的根、把 @ 鍵對映為屬性、把陣列展開為重複元素,並跳脫特殊字元 —— 全程在你的瀏覽器中。如果 JSON 有語法錯誤,會先嘗試修復;你也可以先用 JSON Fix 清理。

常見問題

怎樣把 JSON 轉為 XML?

選一個根元素(單一頂層鍵,或合成的 <root>),然後遞迴地把鍵變成子元素、把 @-前綴鍵變成屬性、把陣列展開為重複元素 —— 同時在文字中跳脫 &<>

JSON 陣列在 XML 中如何呈現?

每個陣列項目都會變成一個獨立的、同名標籤的元素,因為 XML 用「元素的重複」表示列表,而不是單一多值節點。

怎樣讓一個 JSON 值變成 XML 屬性?

給鍵名加上 @ 前綴(例如 "@id"),並把元素的文字放在 #text 之下。這與標準的 XML 轉 JSON 慣例一致,因此轉換可以往返。

如果 JSON 鍵不是合法的 XML 元素名怎麼辦?

XML 標籤名不能以數字開頭或含空白,所以像 "1st place" 這類鍵必須先清洗(例如改為 _1st_place),否則輸出不是格式良好的 XML。

相關工具與指南