JSON 转 XML

在浏览器里把 JSON 转换成格式良好的 XML。可自定义根元素名称,选择是否输出 XML 声明,缩进支持 2 空格、4 空格或不缩进。

把 JSON 树安全地映射成元素。 粘贴 JSON 即可得到格式良好的 XML。数组会展开成重复元素,非法的键名会被修正为合法元素名,声明和缩进则完全由你决定。

XML 输出

如何把 JSON 映射成 XML 而不把自己绕进去

两套模型本来就对不齐

JSON 有六种值类型——对象、数组、字符串、数字、布尔和 null——而且每一种都自带类型信息。XML 只有一种原始类型:文本。其余一切都是由元素和属性搭出来的结构。两者之间并不存在官方映射规则,这也是你遇到的每个转换器行为都略有不同的原因。

这里采用的是最常见、也最可预期的一套约定。对象变成一个元素,它的键成为子元素。字符串、数字和布尔值变成包含其文本形式的元素。null 变成空元素。剩下的就是数组,而 XML 里根本没有对应物:通行的做法是把父元素按条目数重复一遍,于是 {"item": [1, 2]} 变成 <item>1</item><item>2</item>,而不是凭空造一个接收方 schema 并不预期的包装元素。

不是每个 JSON 键都能当元素名

XML 元素名要满足 NCName 规则:以字母或下划线开头,之后可以是字母、数字、连字符、句点和下划线。不能有空格,不能有斜杠,不能以数字开头,也不能以任意大小写的 xml 开头——那是规范保留的前缀。

JSON 键则没有这些限制,它就是任意字符串,真实场景里到处都是 "user name""2024""@type"。原样输出这些名字,得到的文档任何解析器都不会接受。因此非法字符会被替换成下划线,以数字开头的名字前面会补一个下划线。这一步是有损的,所以如果下游真的在意元素名,请先在 JSON 里把键改好,而不是交给转换器去猜。

声明、缩进,以及什么改动是安全的

对 UTF-8 文档来说 <?xml ... ?> 声明是可选的,缺省时解析器就按 UTF-8 处理。当文件要落盘、要通过 HTTP 提供、或者要交给严格的企业流水线时,就带上它;当这段内容要嵌进一份更大的文档时就去掉,因为第二个声明是致命错误。

缩进是更微妙的选择。和 JSON 不同,XML 元素内部的空白属于内容本身,所以美化在技术上确实改变了文档:原本内容是 Ada 的元素,现在装的是换行、若干空格、Ada、换行和更多空格。大多数 schema 会忽略这些差异,但签名校验、xml:space="preserve" 区块以及对空白敏感的格式不会。自己阅读时用缩进,交给机器消费时切回压缩输出。

开源说明:使用原生 JavaScript 实现,不依赖第三方库。

常见问题

我的 JSON 会被上传吗?
不会。整个解析和序列化过程都用浏览器内置的 JSON 函数在本地完成,不会向任何服务器发送数据。
JSON 数组怎么表示?
把父元素按条目数重复一遍。{"item": [1, 2]} 变成 <item>1</item><item>2</item>,这也是多数 XML schema 预期的写法。
键名不是合法元素名时会怎样?
非法字符会替换成下划线,以数字开头则在前面补一个下划线。如果元素名必须精确,请先在 JSON 里改好键名。
为什么输出里没有 XML 声明?
它是可选项,由复选框控制。没有声明时解析器默认按 UTF-8 处理;而且当输出要嵌入另一份文档时,声明必须去掉。
值会被写成属性吗?
不会。所有值都输出为元素文本。属性无法从纯 JSON 推断出来,要做这个判断需要本工具并不具备的 schema 信息。
缩进会改变文档含义吗?
严格说会,因为元素内部的空白属于内容。大多数 schema 会忽略,但涉及签名或对空白敏感的 XML 请使用压缩输出。