关于 XML 格式化与压缩
XML 格式化与压缩工具会重新缩进 XML 文档,让元素嵌套关系可见;需要紧凑载荷时会剥除无意义空白;当标记不再是良构时,也会报告出错的位置。
XML 有一条规则会绊倒所有从 JSON 过来的人:元素内部的空白属于内容。对包含混合内容的文档(例如一个段落里嵌着行内标签)做缩进,会改变解析器读到的文本。因此格式化器必须区分「仅含元素」的内容(加缩进无害)和「混合内容」(加缩进有害)。
如何使用这个开发者工具
- 把文档、SOAP 信封、RSS 源或配置文件粘贴到输入区。
- 选择「格式化」展开嵌套,或选择「压缩」去掉仅位于元素之间的空白。
- 文档被拒绝时,看报告的行号,检查未闭合的标签、落单的 & 符号,或标签名大小写不匹配。
- 复查同时包含文本和子元素的节点,确认格式化器没有动过它内部的间距。
- 复制结果:展开版本用于评审,紧凑版本用于传输。
实例:一条解析不了的订阅条目
这段片段栽在一个 XML 保留字符上。格式化工具会指向实体引用的位置,也就是解析器放弃的地方。
<item>
<title>Q1 results: revenue & margin</title>
<link>https://example.com/report?year=2026&period=q1</link>
</item>EntityRef: expecting ';' at line 2, column 34在 XML 里,裸露的 & 永远表示一个实体引用的开始。两行都受影响:标题里要写成 &,URL 里的 & 要么同样转义,要么把整个值包进 CDATA 段。
必须转义的字符
前两个在任何内容位置都是强制的,其余几个只在所列上下文中强制。
| 字符 | 实体 | 必须转义的位置 |
|---|---|---|
| & | & | 所有文本内容与属性值 |
| < | < | 所有文本内容与属性值 |
| > | > | 建议处处转义;紧跟 ]] 之后必须转义 |
| " | " | 用双引号包裹的属性值 |
| ' | ' | 用单引号包裹的属性值 |
常见问题排查
同一份文档在一个工具里能解析,在另一个工具里失败。
成因 有些读取器对未声明的命名空间前缀、重复属性或缺失的 XML 声明比较宽容,而严格的解析器这三种都会拒绝。
解决办法 先用严格解析器格式化和校验,再逐条修复它报告的问题。被宽容的读取器接受,并不能证明文档良构。
格式化之后,元素内部的文本变了。
成因 该元素是混合内容,格式化器添加的缩进变成了文本节点的一部分。
解决办法 让混合内容元素保持单行,或者把字面文本包进 CDATA,这样任何格式化器都无法重排它。
非 ASCII 字符显示成问号或乱码。
成因 声明的编码与文件实际字节不符,最常见的是 UTF-8 文件被声明为 ISO-8859-1。
解决办法 把 XML 声明中的编码改成文件实际写入时使用的编码,并按该编码重新保存文件。
压缩后的文档让下游消费方出错。
成因 下游依赖了某个含文本元素内部的空白,删掉它就改变了一个值。
解决办法 只压缩「元素要么含文本、要么含子元素、不两者兼有」的文档。拿不准时就发格式化版本。
适合用这个工具的场景
- 把 SOAP 信封或厂商 API 响应读到能找出某一个字段的程度。
- 在提交之前,让构建或应用配置文件变成可评审的样子。
- 把生成的标记交给严格解析器之前,先确认它是良构的。
- 在按字节计费的传输场景下压缩文档体积。
应该换用别的工具的场景
- 按 XSD 或 DTD 校验文档。良构与模式有效是两个问题,前者用 XML 校验工具,后者需要模式处理器。
- 编辑 HTML。HTML5 不是 XML,它容忍 XML 会拒绝的未闭合标签,请改用 HTML 预览工具。
- 把文档转换成另一种结构,那是 XSLT 的工作。
隐私与数据处理
文档在当前浏览器标签页内解析并重新序列化。没有任何内容被上传,关闭标签页后也不留副本。XML 配置文件经常在普通属性里明文写着连接串和凭据,粘贴从运行系统导出的文件前请先删除它们。
相关开发者工具
常见问题
良构的 XML 和有效的 XML 有什么区别?
良构指语法正确:标签正确嵌套、每个元素都闭合、保留字符都做了转义。有效还要求文档符合所声明的模式,例如 XSD 或 DTD。一份文档完全可能良构但无效。
为什么格式化有时会改变我的内容?
因为在 XML 中元素内部的空白属于内容。当一个元素同时包含文本和子元素时,插在它们之间的缩进会成为文本的一部分。格式化器会避开这类元素,但最稳妥的办法仍然是使用 CDATA。
XML 声明是必须的吗?
文档为 UTF-8 且使用 XML 1.0 时可以省略。只要编码不是 UTF-8,或者消费方可能猜错编码,就应当写上。
命名空间是怎么处理的?
前缀声明按原样保留。格式化器不会重写或合并它们,因为同一个前缀在文档后段可能绑定到不同的 URI,改动会改变所有使用它的元素的含义。
带 DOCTYPE 的 XML 文件能格式化吗?
可以,内部子集会被保留。DOCTYPE 引用的外部实体不会被抓取,这同时也是正确的安全行为:解析外部实体正是 XXE 攻击的基础。
为什么我的属性顺序变了?
在这里不会变。XML 认为属性顺序不重要,因此有些工具会重排属性;这对解析器无害,但会让 diff 变得嘈杂,所以这里保留原始顺序。