XML转JSON转换器

浏览器原生 DOMParser 解析 XML,属性映射为 @ 前缀键、重复兄弟元素折叠为数组、CDATA 与实体按规范解码,输出可直接 JSON.parse 的 JSON。

示例已服务端直出:重复的 book 折叠为数组、category 属性带 @ 前缀、CDATA 与 & / < 实体均已按规范解码。点「转换为 JSON」或按 Ctrl/Cmd+Enter 用自己的数据重跑。

映射规则对照表(默认显示 12 行,共 16 行)
XML 构造JSON 结果说明
<bookstore>…</bookstore>(根元素)不单独出现输出取根元素的子节点集合
category="儿童读物"(属性)"@category": "儿童读物"属性统一加 @ 前缀,避免与子元素键冲突
两个同名 <book>"book": [ …, … ]重复兄弟元素折叠为数组
单个 <price>"price": "28.50"单个同名元素不包数组
<price>28.50</price>(纯文本)"28.50"(字符串)不转数字,保留原样避免浮点失真
<title lang="zh">小王子</title>{"@lang":"zh","#text":"小王子"}属性与文本并存时文本落 #text 键
<![CDATA[…]]>并入 textContentCDATA 即字符数据,不再做转义还原
&amp; / &lt;(预定义实体)& / <解析器按 XML 规范自动解码
<!-- 注释 --> 与处理指令丢弃不进入输出
xmlns 与带前缀的标签丢弃前缀与 URI按 localName 输出,命名空间信息不保留
<a/>(空元素)""空字符串
标签间的空白文本节点丢弃仅由空白组成的文本不产生 #text

使用方法

  1. 把 XML 文档粘进左侧输入框,必须是单个根元素的合法 XML 文档。示例数据已服务端直出,打开页面就有内容。
  2. 点「转换为 JSON」,或在输入框里按 Ctrl+Enter(Mac 是 Cmd+Enter)——Enter 本身留给换行。
  3. 解析失败时错误区会给出行列号与原始报错,不会只显示「失败」两个字;成功时右侧输出两空格缩进的 JSON。
  4. 「载入示例」随时把输入恢复为演示文档;「下载 .json」导出不带 BOM 的 JSON 文件(带 BOM 的 JSON 会让 JSON.parse 直接报错)。
  5. 下面的映射规则对照表共 16 行,默认显示 12 行,点「加载更多」看全;「导出 CSV」带 BOM 供 Excel 查阅,「复制对照表」按制表符复制。

这个XML转JSON转换器能解决什么

老系统的接口吐 XML(SOAP、RSS、sitemap、各类企业软件导出),新代码想吃 JSON:本页把两套数据模型之间的翻译规则定死——属性去哪、同名子元素怎么办、文本和属性并存时谁让路——同一段 XML 转一百次结果一致,方便直接写快照测试。

调接口时想快速确认「这个字段到底是元素还是属性」:粘进来一眼看出 category 变成了 @category,文本内容落到了 #text,不用翻对方文档。

排查「为什么我的 XML 解析不了」:DOMParser 的报错信息带行列号,本页原样透出,比后端日志里被包装过的话术好定位。

本页不做的事:不做 XML 格式化与缩进美化——那是XML格式化的领域;不做反向转换,JSON 变 XML 请用JSON转XML转换器;也不校验你的 JSON 输出结构是否满足某个接口约定,映射规则以本页对照表为准。

原理与规则说明

XML转JSON转换器的解析调用是 new DOMParser().parseFromString(text, 'application/xml')。MIME 类型参数决定行为:用 application/xml 时标签大小写原样保留、未闭合标签直接报 parsererror;换成 text/html 会把标签全部转小写、自动补全未闭合标签、把 XML 声明当注释吞掉——本页固定 application/xml,就是要它的严格模式。解析失败时文档里会出现 <parsererror> 节点,本页读出它的文本内容(含行号列号)原样透出。

映射规则共 16 条(见对照表),核心四条:属性统一加 @ 前缀,这样 <a b="1">2</a> 不会和子元素 <b> 撞键;文本与属性或子元素并存时文本落 #text 键;同名兄弟元素按出现次数折叠——两个以上成数组、恰好一个保持标量,数组与否由数据本身决定,不做猜测;纯文本元素输出字符串且不转数字,28.50 保持 "28.50",避免 0.1 + 0.2 那类浮点失真和前导零丢失。

CDATA 与实体由解析器处理:<![CDATA[…]]> 的内容就是字符数据,本页通过 textContent 取回时它已与普通文本合并,不需要也不应该再做反转义;&amp;、&lt; 等预定义实体同理,到 JSON 输出里已经是解码后的 & 和 <。CDATA 内唯一非法的序列是 ]]>,出现它解析器会直接报错。

命名空间是有意丢弃的:带前缀的标签(如 <ns:title>)按 localName 输出成 title,xmlns 与 xmlns:* 声明不进入输出。理由是 JSON 没有命名空间概念,任何「保留」都只能是把 URI 硬编码进键名,反而制造跨系统不可比对的键。如果你的数据靠前缀区分语义,请先在源头合并前缀。

输入到输出的完整链路:读文本 → 长度校验(超 200 KB 提示、超 2 MB 拒绝)→ DOMParser 严格解析 → 深度优先遍历根元素的子节点 → 注释与处理指令跳过 → 每个元素按「属性 → 子元素分组 → 文本」三段拼对象 → JSON.stringify(…, null, 2) 输出。全程只依赖浏览器原生 API,没有第三方解析库。

完整示例(数值仅作演示)

演示文档里藏着五条最容易踩的规则:两个 <book> 折叠成数组;category="儿童读物" 带 @ 前缀;<title lang="zh">小王子</title> 变成 {"@lang":"zh","#text":"小王子"};stock 里的 CDATA 原样取出 数量 > 100 && 状态 < 正常;note 里的 &amp; 与 &lt; 解码成 & 与 <。打开页面就能在右侧看到这份输出。

结构核对:输出顶层应当恰有 book、stock、note 三个键;book 是长度 2 的数组;两个 price 都是字符串不是数字。把右侧文本粘进 JSON.parse 应当不抛错。

报错示例:把演示文档里任意一个 </book> 删掉再转换,错误区会显示 parsererror 的原文,类似「error on line 5 at column 4: mismatched tag」,行号直接指向被删标签之后的位置。

命名空间演示:把根标签写成 <bookstore xmlns:ns="urn:x"> 并把一个 book 改成 ns:book,输出的键仍是 book——前缀与 URI 都被丢弃,这是上面说的既定规则。

输入范围与对照表

输入范围:单根元素的合法 XML 文档;超过 200 KB(204,800 字节)时结果区提示可能变慢,超过 2 MB(2,097,152 字节)直接拒绝——几 MB 文本的解析加序列化会卡死标签页。深度与节点数没有单独上限,受 2 MB 字节上限间接约束。

映射规则对照表(工具区,16 行)覆盖:根元素、属性 @ 前缀、重复兄弟折叠数组、单元素保持标量、纯文本不转数字、属性文本并存落 #text、CDATA 并入、实体解码、注释与处理指令丢弃、命名空间丢弃、空元素、空白文本节点,外加深度嵌套、大小写保留、混合内容、多根报错四条,加载更多后可见。CSV 导出带 BOM。

与 JSON 族其它页的分工:转换完想缩进排版交给JSON美化打印,想验证语法交给JSON校验;本页只保证输出的 JSON 语法合法,不替你确认业务结构。

输入范围、边界与精度说明

大小写完全保留:<Book> 与 <book> 在 XML 里是两个不同元素,输出就是两个不同的键——这与 text/html 模式全转小写的行为相反,也是本页坚持 application/xml 的原因之一。同理,键名里的中文、数字开头等「JSON 不常规」的名称原样保留,JSON 语法允许任意字符串键。

精度规则:所有文本值一律字符串,28.50 不会变 28.5,007 不会变 7,超出 2^53(9 007 199 254 740 991)的长 ID 也不会丢精度。需要数字类型请在下游用 Number() 显式转换并自行承担舍入。

混合内容(一个元素里既有文本又有子元素)的文本全部合并进 #text,元素间的顺序信息会丢失——JSON 对象没有「键在文本之前还是之后」的表达力。空白文本节点(缩进换行)不产生 #text,但文本内部的前后空白会按 trim 后保留中间内容。

每条非法路径的具体文案:空输入提示粘贴或载入示例;超 2 MB 报出实测字节数;parsererror 附原始报错含行列号;没有根元素的片段(如只粘了 <a/><b/>)会以「存在多个根元素」的报错拒绝;XML 声明不在首行也会被严格模式拒绝。以上都不会静默输出半个结果。

常见误用一:以为输出数组的顺序保证与源文档一致——同名兄弟元素按文档顺序进数组,这点有保证;但跨键名之间的顺序只按首现顺序,JSON 消费方不应依赖键序。误用二:拿本页输出直接反推 XML Schema——@ 前缀与 #text 都是本页约定,不是 W3C 标准,跨工具不可移植。

常见问题

为什么属性要加 @ 前缀?

这是本页的映射约定:JSON 对象里属性和子元素都表现为键,不加前缀时 <a id="1"><id>2</id> 会撞键。@ 前缀与 #text 一样是大量 XML 转 JSON 工具的通用惯例,对照表里有完整清单。

命名空间去哪了?

丢弃。JSON 没有命名空间模型,把 URI 编进键名会让输出不可比对。本页按 localName 输出;依赖前缀区分语义的数据请在源头处理。

数字为什么变成字符串?

保真优先。28.50 转成数字会丢尾零,007 会丢前导零,长 ID 会越过安全整数上限丢精度。字符串是唯一无损的通道,需要数字请下游显式转换。

解析报错为什么是英文?

报错原文来自浏览器 DOMParser,本页原样透出不翻译——翻译反而丢失行列号信息。文案开头会用中文说明出错环节,后面的原文直接定位到行列。

能不能转回 XML?

本页不做反向转换。JSON 的对象键到 XML 标签的映射是另一套约定(文本节点怎么命名、数组怎么重复),请用 JSON转XML转换器。

CDATA 里的内容会被转义吗?

不会。CDATA 本身就是「不需要转义的字符数据」,解析后与普通文本合并,输出即原始内容。唯一非法序列是 ]]>,出现即解析报错。

超过 2 MB 怎么办?

先拆分。按顶层元素切成多份分别转换,或改用命令行工具;浏览器单页一次解析几 MB 文本会卡顿甚至崩标签页,硬扛不值得。

输入的 XML 会被上传吗?

不会。解析与序列化全部用浏览器原生 API 在本地完成,没有任何网络请求,开发者工具 Network 面板可自查。

相关工具

XML转JSON转换器只管「XML 进、JSON 出」这一段,前后两端的常见需求各有专门页面。