XML 格式化 / 压缩
按标签层级缩进,或压缩成紧凑单行
XML 格式化:合法性要求与"格式化可能改变语义"的例外
XML 比 HTML 严格得多
XML 解析器不做容错推断,一条不合法的 XML 会直接解析失败。格式化的输出要能被重新解析,就必须满足这些要求:
| 要求 | 说明 |
|---|---|
| 唯一根元素 | 整个文档只能有一个最外层元素 |
| 标签必须闭合 | 没有 <br> 这种"空元素可省略"的特例;要么 <br/> 要么 <br></br> |
| 大小写敏感 | <Name> 与 <name> 是不同元素,闭合标签必须完全一致 |
| 属性必须加引号 | 单引号或双引号都可以,但不能省略 |
| 特殊字符必须转义 | & → &,< → <,> → > |
| XML 声明必须在最前 | <?xml version="1.0" encoding="UTF-8"?> 之前不能有任何内容(连空白也不行) |
第五条是最常导致解析失败的:& 在 XML 里只能作为实体的开始,正文中的裸 & 必须写成 &。URL 参数里的 &(如 ?a=1&b=2)如果直接放进 XML 文本,就会让解析失败。
格式化会改变语义的例外
这一点很重要,而且经常被忽略:XML 规范认为元素内的空白是有意义的。格式化插入的换行与缩进会被解析成文本节点的一部分。
| 情况 | 格式化的后果 |
|---|---|
纯元素内容(如 <a><b/></a>) | 通常无影响,多数应用会忽略元素间的空白 |
| 混合内容(既有文本又有子元素) | 插入换行会改变文本内容,可能破坏显示或校验 |
文本元素(如 <name>Bob</name>) | 在标签内插入换行会变成值的一部分,导致校验或比对失败 |
声明了 xml:space="preserve" 的元素 | 必须完全保留原有空白,不能重新缩进 |
所以实用判断是:如果 XML 的 schema 没有把元素间空白声明为可忽略,格式化就是有风险的操作。两种情况尤其要避开:
- 用于数字签名的 XML。XML 签名(XMLDSig)对文档的规范化形式做签名,任何空白改动都会导致签名校验失败。这类文档绝对不能格式化。
- 带混合内容的文档(如 XHTML、DocBook、SVG 中含文字的段落)。
另外 <![CDATA[...]]> 段落内的内容是原始文本,不能重新缩进。工具会保持 CDATA 内容原样。
压缩(minify)
压缩删除元素之间的空白与换行。同样的条件适用:只在确定空白可忽略时才安全。压缩后的文档在网络传输上确实能省一些体积(XML 标签重复度高,配合 gzip 后压缩收益更小)。
压缩会带来一个副作用:出问题时排查困难。建议保留一份未压缩版本,只把压缩产物用于传输。
与 XML 转 JSON 的分工
| 需求 | 用哪个 |
|---|---|
| 让 XML 变整齐、可读 | 本工具 |
| 验证 XML 是否格式良好 | 本工具(不合法时会失败);校验是否符合 schema 需要专门工具 |
| 把 XML 转成 JSON 结构 | XML 转 JSON 工具(用浏览器解析器,能正确处理实体与 CDATA) |
| 查看某段 XML 里有哪些字段 | XML 转 JSON 更直观,但要注意属性与单值/数组的歧义 |
工具怎么用
粘贴 XML,点格式化得到层级缩进,或点压缩得到紧凑单行。适合阅读接口返回的 XML、检查嵌套层级、整理配置文件。处理在浏览器本地完成——接口返回里常含业务数据,本地处理是必要前提。
常见问题
标签之间多余的空白会怎么处理?
格式化时会去掉标签之间的纯空白文本,只对标签内真正的文本内容缩进保留。
压缩会改变节点顺序吗?
不会。压缩只删除标签间的空白,节点与属性顺序完全不变。