XML 转 JSON 转换器
即时在 XML 和 JSON 格式之间转换
在浏览器中把 XML 与 JSON 双向互转。属性、重复元素和混合文本都按广泛使用的 @ 与 #text 约定映射,因此往返转换能保留数据。粘贴 API 响应、配置文件或 RSS 订阅源即可得到可读的 JSON,也可以把 JSON 转成带缩进、合法的 XML 文档。
映射规则
XML 能表达 JSON 无法直接表达的内容:一个元素可以同时携带属性、包含文本并拥有子元素。本转换器用一组小而对称的规则来表示这些信息。
| XML 结构 | JSON 表示 |
|---|---|
| 属性 id=“42” | 键 “@id”: “42” |
| 叶子文本,无属性也无子元素 | 普通字符串值 |
| 文本与属性或子元素共存 | ”#text”: ”…” |
| 重复的同名兄弟标签 | 值数组 |
| CDATA 区块 | 文本内容 |
对称性才是关键:以 @ 开头的键会被写回属性,#text 会成为元素的文本,数组会展开为重复元素。正因如此,XML → JSON → XML 才是一次稳定的往返。
实操示例:一个用户文档
以下面的输入为例:
<users>
<user id="1">
<name>Alice</name>
<email>alice@example.com</email>
</user>
<user id="2">
<name>Bob</name>
<email>bob@example.com</email>
</user>
</users>
根元素名会成为最外层的键。每个 user 都带有 @id 属性和若干子元素,因此各自变成一个含 @id、name、email 的对象。由于两个 user 元素同名且互为兄弟,user 键会变成数组:
{
"users": {
"user": [
{ "@id": "1", "name": "Alice", "email": "alice@example.com" },
{ "@id": "2", "name": "Bob", "email": "bob@example.com" }
]
}
}
内部的 name 和 email 既没有属性也没有子元素,因此各自折叠为普通字符串,而不是对象。
混合内容与 CDATA
当文本与属性同时存在时,文本会移到 #text 下。
JSON 转 XML:根元素、缩进与转义
反向转换时,单键对象会成为自己的根元素,而多个键、数组或原始值会被包进
常见错误与局限
- 期待带类型的值。 XML 里的所有内容都是文本,所以数字和布尔值到 JSON 中都是字符串;类型重要时请自行转换。
- 依赖混合内容的顺序。 文本会被拼接并去除空白,子元素相对文本的位置无法还原。
- 忘了数组需要有重复标签。 一个 JSON 对象数组会变成同名的重复元素,没有单独的列表包装。
- 使用非法键名。 JSON 键里的空格、前导数字或其他非法字符会让 JSON → XML 转换报”非法名称”错误。
- 以为属性顺序随意也能保持不变。 属性按 JSON 键顺序输出,在 XML → JSON 中 @ 键会插在子元素键之前,因此顺序稳定,但不一定等于原文档顺序。
- 把超大文档塞进复制按钮。 格式化后的输出很长,剪贴板操作很笨重,这种情况请改用下载按钮。
适用场景
- 遗留系统与 SOAP API。 许多企业服务仍返回 XML。先把响应转一次、在 JSON 查看器里看清结构,再按 @ 和 #text 键写代码。
- 配置迁移。 pom.xml、web.config 或 Android 清单等文件转成 JSON 后,更容易用脚本做 diff 和转换。
- RSS 与 Atom 订阅源。 订阅源条目会变成 channel 键下的 JSON 数组,无需 XML 库即可过滤和渲染。
- 数据交换。 当下游系统只接受 XML 时,用 JSON 构建对象,让工具输出转义处理妥当的合法文档。
- 往返校验。 把 XML 转成 JSON 再转回来,确认两个方向一致,再接入流水线。
有一点适用于以上所有场景:这套映射是一种约定,而不是通用标准。如果另一个系统习惯把属性写成内联、或把元数据包在 _attributes 之类的键下,它的 XML 转 JSON 结果不会与本工具一致,尽管两者都是合法 JSON。请按你的消费方所期望的约定来,不要假设经由别的工具往返后还能对得上。
对于大型订阅源,优先用下载而不是复制:几千个条目的格式化 JSON 很长,浏览器处理文件比处理选区更稳。转换器不做流式处理,超大文档会在转换两侧都作为文本驻留内存;如果页面变卡,请把巨型文件拆分成按条目分块处理。
相关工具
常见问题
什么时候文本会变成普通字符串,而不是 #text?
当一个元素既没有属性也没有子元素时,它会直接折叠为去掉首尾空白后的纯文本字符串。一旦该元素同时带有属性或子元素,文本就会改存到 #text 键下,因为对象里还有别的键与它并列。
混合内容里文本夹在子元素之间会怎样?
元素内所有文本节点会先被拼接、去除首尾空白,然后统一存入一个 #text。原始的交错顺序会丢失,所以 <p>你好 <b>世界</b> 再见</p> 只得到 #text "你好 再见",而不会按位置还原。
JSON 有多个顶层键时,用什么根元素?
单键对象会直接用它自己的键名作为根元素。其他情况——多个键、数组或原始值——都会被包进名为 root 的元素。输出文档始终以 version 1.0、UTF-8 的 XML 声明开头。
实体和 CDATA 区块会被解码吗?
文本和属性值中的命名实体与数字字符实体会被解码为对应字符。CDATA 区块按文本内容处理,因此它会像普通文本一样进入 #text,或在纯净叶子元素中折叠成普通字符串。
为什么转换后数字和布尔值都变成了字符串?
XML 本身没有类型概念,所有内容都是文本,因此 42 会变成 "42",true 会变成 "true"。如果下游需要真正的数字或布尔值,请在拿到 JSON 后自行转换。
键名不合法时会发生什么?
JSON → XML 方向会校验键名是否符合 XML 命名规则:必须以字母或下划线开头,只能包含字母、数字、点、下划线、冒号和连字符。含空格或以数字开头的键会直接报告为非法名称,而不是生成损坏的标记。
由 HandyTools Hub 团队审校 · 最后更新