XML 格式化工具
什麼是 XML 格式化?
XML 格式化工具用來把壓縮、混亂或難以閱讀的 XML 轉成有縮排的清楚結構。XML 常見於設定檔、SOAP 訊息、網站地圖、RSS、辦公文件、建置產物和許多舊系統整合中,一個缺少的結束標籤或跳脫錯誤都可能導致解析失敗。格式化後,巢狀元素、屬性、文字節點、命名空間和可疑錯誤位置會更容易觀察,適合除錯、文件整理、版本比較和教學說明。需要注意的是,格式化提升的是可讀性,並不等同於依 XSD、API 契約或合作方格式完成校驗;無效 XML 不會因為縮排變正確。
使用方式
使用方式
- 在左側輸入方塊中貼上或輸入 XML 資料
- 選擇縮排大小(2 個空格、4 個空格或 Tab)
- 點選「Format」美化或「Minify」移除空白
- 結果會顯示於右側並附語法高亮
- 點選「Copy」或「Download」儲存結果
XML 說明
- 格式化只會改變空白,不會改變文件意義;但在文字節點和混合內容文件中,空白仍可能有影響。
- 若解析失敗,請檢查未關閉的標籤、巢狀結構不對稱、重複的屬性,以及未跳脫的字元(如 & 號)。
使用場景
`(XML 1.0 §3.1 接受的 SGML 功能)會保持原樣,因此在 XHTML 或 RSS 中的 HTML 空元素必須保留斜線;若改成 `
`,HTML5 解析器會默默改變渲染結果。CDATA 區塊(包括結尾的 `]]>` 規則)也會完整保留,不會被還原成 `&` 實體。
技術原理
XML 格式化以 W3C XML 1.0(第五版)建議書為基礎。解析透過 `new DOMParser().parseFromString(src, 'application/xml')`(或 `text/xml`)進行,傳回一個 Document,其節點符合規範中定義的七種產物:Element、Attr、Text、CDATASection、Comment、ProcessingInstruction 和 DocumentType。與 HTML 不同,XML 解析器是嚴格的:不匹配的標籤、未跳脫的 `&` 或重複的屬性都會中止解析,DOMParser 會傳回一個 `<parsererror>` 元素,其內容包含行號和欄號。服務端等效工具包括 libxml2(`xmllint --format`)、Python 的 `xml.etree.ElementTree`、Java 的 StAX/SAX 以及 .NET 的 `XmlReader`。 列印器逐節點序列化 DOM:每個 Element 在自己的行上以 depth*indent 個空格開啟,子元素以 depth+1 遞迴,結束標籤與開始標籤對齊,空元素折疊為自閉合簡寫 `<foo/>`,規範 §3.1 聲明其與 `<foo></foo>` 語義等價。五個預定義實體在文字和屬性值中始終重新編碼:`&` `<` `>` `"` `'`。CDATA 區塊(`<![CDATA[ ... ]]>`)逐字保留,因為它們是處理原本需要實體編碼的內容的明確逃生機制;終止符 `]]>` 不能出現在 CDATA 區塊內部(§2.7),解析器會強制執行此規則。處理指令如 `<?xml-stylesheet?>` 和 XML 宣告 `<?xml version="1.0" encoding="UTF-8"?>` 保留在文件序言。DOCTYPE 宣告以單一字串進行往返。 兩個微妙之處構成了格式化器的大部分複雜度。首先,混合內容——同時包含文字和子元素的元素,如 `<p>Hello <b>world</b>!</p>`——無法在不改變文件資訊集的情況下重新縮排,因為此上下文中的每個空白字元都是有意義的 Text 節點。格式化器透過掃描 Element 是否有任何非空白 Text 子節點來偵測混合內容,並對該子樹切換為單行序列化。其次,命名空間宣告(`xmlns`、`xmlns:prefix``)必須留在首次宣告它們的元素上;移動它們會改變作用域。根據規範,屬性順序不是規範的,因此大多數格式化器在保留任何前置 `xmlns:*` 宣告的同時,套用字母排序。解析和序列化的時間複雜度相對於文件長度為 O(n);非常大的 feed 通常透過 SAX 串流處理,而非在記憶體中建立 DOM。
- 規範:W3C XML 1.0 第五版(REC-xml-20081126);DOM 透過 `DOMParser().parseFromString(src, 'application/xml')` 建構,等效於服務端的 libxml2 或 `xmllint --format`。
- 設計上嚴格:不匹配的標籤、未跳脫的 `&`/`<`、重複屬性或無效字元會觸發 `<parsererror>` 元素;HTML 的容錯恢復機制不適用。
- 五個預定義實體在文字和屬性值中重新編碼:`&` `<` `>` `"` `'`。數字字元參照如 ` ` 則原樣保留。
- 自閉合 `<foo/>` 與 `<foo></foo>` 根據 §3.1 語義相同;CDATA 區塊逐字保留且不得包含終止符 `]]>`。
- 混合內容(文字 + 子元素)無法在不改變資訊集的情況下重新縮排——列印器偵測到有意義的空白後,將這些子樹以行內方式序列化。
- 命名空間宣告(`xmlns`、`xmlns:prefix`)留在首次宣告的元素上;移動它們會改變作用域。屬性順序不是規範的,因此穩定排序(xmlns 優先,然後字母排序)是典型做法。
- 複雜度:基於 DOM 的工具為 O(n) 解析和 O(n) 序列化;大型文件透過 SAX/StAX(Python 的 xml.sax、Java 的 javax.xml.stream)串流處理,以避免將整棵樹載入記憶體。
範例
基本元素
<!-- 輸入(單行) -->
<book><title>XML Guide</title><author>Jane Doe</author><year>2024</year></book>
<!-- 輸出(2 個空格) -->
<book>
<title>XML Guide</title>
<author>Jane Doe</author>
<year>2024</year>
</book>含屬性
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="b001" lang="en" available="true">
<title>Effective XML</title>
<price currency="USD">29.99</price>
</book>
</catalog>含命名空間與 CDATA 的巢狀結構
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns:GetUser xmlns:ns="https://example.com/api">
<ns:UserId>10086</ns:UserId>
<ns:Script>
<![CDATA[ if (a < b && b > 0) { return true; } ]]>
</ns:Script>
</ns:GetUser>
</soap:Body>
</soap:Envelope>常見問題
這個工具的功能是什麼?
美化 XML:縮排巢狀元素、讓每個元素獨立成行、對齊結束標籤。適合用來檢視被擠成一整行的 SOAP 回應、RSS feed、設定檔或其他 XML 內容。
會依結構描述(Schema)驗證嗎?
不會。本工具只負責格式化你貼上的合法 XML。Schema(XSD、DTD、RELAX NG)驗證需要另外的工具。格式錯誤(標籤不對應、缺少結束括號)會被回報,但本頁不會自動修復。
會保留屬性順序嗎?
會。XML 規格上屬性順序並不具語意,但本工具會保留原始順序,避免你誤判結果。CDATA 區段、註解、處理指令也都會保留。
空白是怎麼處理的?
元素之間的空白會被正規化(每個元素一行並加上縮排)。文字內容裡的空白預設會保留,因為元素內容具有語意。若有 xml:space='preserve' 屬性也會被遵守。
可以壓縮(minify)XML 嗎?
部分版本提供 minify 模式,會移除元素之間的空白。要小心:原本有意義的空白(文字內容、xml:space='preserve' 區段)必須保留。如果你的 XML 含有複雜文字內容,請測試往返結果是否一致。
XML 內容會被上傳嗎?
不會。解析與美化都在你的瀏覽器中透過 DOMParser 與 XMLSerializer(瀏覽器內建)執行,不會傳送任何內容。
XML 命名空間呢?
命名空間宣告(xmlns)以及帶字首的元素/屬性會原封不動格式化。即使在巢狀元素中重複宣告同一個命名空間也會被保留(有些驗證器在意,有些不在意)。