XML 格式化工具
什么是 XML 格式化?
XML 格式化工具用于把压缩、混乱或难以阅读的 XML 转成带缩进的清晰结构。XML 常见于配置文件、SOAP 消息、站点地图、RSS、办公文档、构建产物和许多旧系统集成中,一个缺失的闭合标签或转义错误都可能导致解析失败。格式化后,嵌套元素、属性、文本节点、命名空间和可疑错误位置会更容易观察,适合调试、文档整理、版本比较和教学说明。需要注意的是,格式化提升的是可读性,并不等同于按 XSD、API 契约或合作方格式完成校验;无效 XML 不会因为缩进变正确。
使用方法
使用方法
- 在左侧输入框中粘贴或输入 XML 数据
- 选择缩进大小(2 个空格、4 个空格或 Tab)
- 点击「格式化」进行美化,或点击「压缩」移除空白
- 结果在右侧显示并带有语法高亮
- 点击「复制」或「下载」保存结果
XML 说明
- 格式化只改变空白,不影响文档含义,但在文本节点和混合内容文档中空白仍然有意义。
- 如果解析失败,请检查未闭合的标签、不匹配的嵌套、重复的属性以及未转义的字符(如 & 符号)。
使用场景
` 这样的自闭合简写(SGML 特性,XML 1.0 §3.1 接受)会原样保留,因此在 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[ ... ]]>`)原样保留,因为它是对需要实体编码的内容的显式转义机制;规范 §2.7 禁止 CDATA 块内出现终止符 `]]>`,解析器会强制执行此规则。处理指令(如 `<?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);超大型数据流通常使用 SAX 流式处理,而非在内存中构建 DOM。
- 规范:W3C XML 1.0 第五版(REC-xml-20081126);DOM 通过 `DOMParser().parseFromString(src, 'application/xml')` 构建,服务端等价于 libxml2 或 `xmllint --format`。
- 严格解析:标签不匹配、未转义的 `&`/`<`、重复属性或非法字符会触发 `<parsererror>` 元素;HTML 的容错恢复机制不适用于 XML。
- 五个预定义实体在文本和属性值中重新编码:`&` `<` `>` `"` `'`。数字字符引用(如 ` `)原样保留。
- 自闭合 `<foo/>` 和 `<foo></foo>` 在语义上等价(规范 §3.1);CDATA 段原样保留,且不得包含终止符 `]]>`。
- 混合内容(文本 + 子元素)无法在不改变信息集的情况下重新缩进——序列化器检测到有意义的空白后会将该子树内联输出。
- 命名空间声明(`xmlns`、`xmlns:prefix`)保留在首次声明的元素上;移动它们会改变作用域。属性顺序不是规范化的,通常按稳定排序(xmlns 在前,其余按字母排列)。
- 复杂度:DOM 模式下解析和序列化均为 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 订阅源、配置文件以及那些挤成一行的 XML 数据。
会校验 schema 吗?
不会。本工具只对你粘贴的格式良好的 XML 进行排版。schema(如 XSD、DTD、RELAX NG)校验需要专门的工具。格式错误(标签不匹配、缺少闭合括号)会被报告,但页面不会自动修复。
属性顺序会被保留吗?
会。从规范上讲 XML 属性顺序并无意义,但格式化工具会保留原始顺序,避免出乎意料。CDATA 段、注释和处理指令也都会被保留。
空白字符是怎么处理的?
元素之间的空白会被规范化(每行一个元素并带缩进)。文本内容内部的空白默认保留——元素文本是有意义的。带 xml:space='preserve' 属性的部分会被严格保留。
可以压缩 XML 吗?
部分版本提供压缩模式,可去除元素间的空白。注意:任何有意义的空白(文本内容、xml:space='preserve' 区域)都应被保留。如果你的 XML 含有富文本内容,建议先做一次往返测试。
XML 会被上传吗?
不会。解析和美化都在浏览器中通过 DOMParser 和 XMLSerializer(浏览器原生 API)完成,不会上传任何内容。
XML 命名空间怎么处理?
命名空间声明(xmlns)以及带前缀的元素或属性会按原样格式化。在嵌套元素中重复声明同一命名空间也会被保留(部分校验器会在意,部分则不会)。