繁體中文

開發者工具·語法轉換器

XML 到 JSON 映射:屬性、文字節點和一對多問題

· 工作原理

xml json 資料格式

一個 XML 項映射到對象,而重複項映射到數組
原始 ToolAcre 向量圖

沒有唯一正確的方法可以將 XML 轉換為 JSON,因為 XML 具有 JSON 所缺乏的屬性、混合內容和有序子項。這篇文章解釋了常見的映射約定以及每個約定中的陷阱。

為什麼一個 <item> 成為一個對象,兩個成為一個數組 - XML feed 的 JSON 形狀根據它有多少條目而變化

具有 `<item>one</item>` 的 Feed 會產生 `"item": "one"`;新增第二個同級將該屬性變更為 `"item": ["one", "two"]`。解析器無法推斷出一項在概念上是一項的列表,因為這兩種意義具有相同的 XML 語法。因此,當生產發送第二個樣本時,僅針對第一個樣本建立的程式碼可能會失敗。

ToolAcre 並沒有將這種不穩定性隱藏在始終數組選項後面。它將名稱一次記錄為一個值,並將重複的同級記錄為一個陣列。這種直接映射很容易檢查,但需要穩定集合形狀的消費者必須使用模式知識或在轉換後自行標準化結果。

XML 具有 JSON 所沒有的特性 — 屬性、與元素混合的文字、有序同級、命名空間、註解和處理指令

XML 將屬性與子元素分開,保留同級順序,允許元素之間存在文字,攜帶命名空間前綴,並可以包含註釋和處理指令。 JSON 提供物件和數組,但沒有這些節點類別的內建等效項。因此,任何 XML 到 JSON 結果都是選定的投影,而不是通用翻譯。

該讀者刪除宣告、註解和處理說明。命名空間前綴保持逐字而不是被解析:`<ns:item>` 變成鍵 `ns:item`,而 `xmlns:ns` 變成 `@xmlns:ns`。混合文字是在一個鍵下連接的,因此它在子元素周圍的原始位置會遺失,並會出現警告,表示轉換無法往返。

屬性約定 - @ 或 $ 等前綴、它們存在的原因以及同名屬性和子元素如何衝突

屬性使用 `@` 前綴。 `<user id="7"><id>other</id></user>` 變成 `@id` 等於 `"7"` 且子 `id` 等於 `"other"` 的物件。此前綴可防止兩個不同的 XML 建構在單一物件屬性中發生衝突。當 JSON 寫回 XML 時,它也成為轉換器合約的一部分。

其他函式庫可能使用 `$`、屬性物件或其他約定。 ToolAcre 僅支援可見的 `@` 映射。在不更改編寫器的情況下更改應用程式程式碼中的前綴會將屬性轉換為元素,因此在使用轉換後的值作為中間檢查形式時保留它。

文字節點約定 — #text 或 _ 表示元素內容,以及當元素同時具有文字和子元素時會發生什麼

僅包含文字的元素會折疊為該字串。當屬性或子屬性也存在時,文字位於 `#text` 下; CDATA 單獨保存在 `#cdata` 下。自閉合標籤變成空字串。這些保留鍵可讓編寫者將普通子名稱與 JSON 本身未定義的內容類別區分開來。

混合內容仍然有損。在 `<p>before<b>bold</b>after</p>` 中,相對於子項的「之前」和「之後」位置無法從連接的 `#text` 屬性中重建。該工具會偵測該結構模式並發出警告。當檔案順序是意義的一部分時,請使用保留節點的 XML API。

一對多問題 - 重複元素僅在重複時才變成數組,以及為什麼消費者必須防禦性編碼

僅在觀察到重複後,重複的同級才會轉為陣列。單一 `<book>` 是一個物件;兩本書是一個物件陣列。這有時稱為一對多問題,但這不是解析器缺陷。來源檔案根本不包含與其出現無關的清單宣告。

防禦性消費者可以使用模式知識規範已知路徑:當 `catalogue.book` 還不是陣列時,將其包裝起來。不要將該規則應用於每個屬性,因為普通標量不應僅僅為了對稱而成為列表。轉換器故意避免發明此類域資訊。

工作範例:轉換一個小型 RSS 樣式檔案 — 屬性、重複元素和命名空間,並附註解的結果 JSON

轉換 `<feed xmlns:m="https://example.invalid/meta"><item id="1"><m:title>One</m:title></item><item id="2"><m:title><![CDATA[Two & More]]></m:title></item></feed>`。根目錄是 `feed`; `@xmlns:m` 保留命名空間宣告; `item` 是一個陣列;每個 `@id` 都是文字;第二個標題包含 `#cdata`。

類型推斷預設處於關閉狀態,因此即使 `id="2"` 仍保留字串 `"2"`。啟用推理可以讓解析器將數字和布林文字讀取為 JavaScript 類型,但 XML 沒有宣告該意圖。該選項是用戶控制的猜測,而不是檔案提供的證據。

這不包括什麼 - 模式驅動的轉換知道元素始終是列表,這需要 XSD 或手動映射

未載入 XSD,且沒有可用的架構驅動清單資訊。當僅出現一個元素時,轉換器無法知道該元素是可重複的,無法驗證所需的子元素,無法將名稱空間 URI 解析為應用程式類型或產生類型化用戶端。成功的解析僅建立已設定的讀取器所接受的格式良好的 XML 。

DOCTYPE 宣告在解析之前被拒絕,包括無害的宣告。此邊界可防止外部實體請求、本機檔案讀取和實體擴充。刪除 DOCTYPE 也可能會刪除檔案所依賴的宣告,因此只有當您擁有資料並了解後果時才可以這樣做。

重點:XML 到 JSON 是映射,而不是翻譯 - 以及語法轉換器面板如何讓您在瀏覽器中檢查該映射

將結果視為 ToolAcre 的記錄映射:`@` 用於屬性,`#text` 用於混合元素文字,`#cdata` 用於 CDATA,重複同級和文字命名空間前綴之後的數組。這些規則使輸出可預測,而無需假裝 XML 和 JSON 共用一個資料模型。

對於檢查而言,此投影快速且可讀取。為了實現持久集成,請測試一個或多個出現情況、與子級共享名稱的屬性、空元素、混合內容和命名空間。如果元素順序或模式限制很重要,請根據該約定解析 XML 而不是依賴通用轉換後的形狀。

將原始 XML 固定裝置保留在標準化期望旁邊。如果相依性升級更改了陣列處理、空白修剪或實體解碼,則該配對會保留證據。它也為審閱者提供了一個查看 JSON 視圖無法實現的差異的地方。僅轉換後的物件無法證明空字串是否來自自閉合元素、配對標籤或來源中的其他約定。