piapia123
zh

XML 与 JSON 互转

格式化

所有处理都在浏览器本地完成,数据不上传服务器

输入
把文件拖到这里可直接载入
输出

⚠️ 这个转换天然有损,而且丢的东西比看上去多。 XML 与 JSON 的数据模型不一样,不是两种写法的问题: · 属性 vs 子元素 —— `<a b="1"/>` 与 `<a><b>1</b></a>` 在 XML 里是两件不同的事(元数据 / 内容)。转成 JSON 靠 `@` 前缀区分,转回去能还原。 · 混合内容 —— `<p>前面<b>粗</b>后面</p>` 里文字与元素是交错的。JSON 的对象没有顺序概念,这一层结构必然丢失。 · 重复标签 —— 出现两次变数组、一次是标量,于是 JSON 里看不出「只有一个」与「只会有一个」的区别;转回去时一个单元素数组会变成单个元素。 · 注释、处理指令、DOCTYPE —— JSON 里没有对应物,丢弃并计数。 · 命名空间 —— 前缀连同标签名保留(`xs:element`),但不做命名空间解析:两段前缀不同却指向同一命名空间的文档,转出来是不同的键。 所以这里用一套固定的约定转换,并把上面这些丢失逐条报出来(数出注释几条、哪几个元素是混合内容)—— 而不是安静地给出一份看起来完整的 JSON。 ⚠️ 根元素不展开:`<a><b>1</b></a>` 转成 `{"a":{"b":"1"}}`,不是 `{"b":"1"}`。展开看起来更干净,但它会让反方向彻底做不了 —— `{"b":"1"}` 转回 XML 时根元素该叫什么?名字已经在那一步丢掉了。这个工具是双向的,两边必须共用一套约定。全部在浏览器本地完成。

功能

  • 两个方向:XML → JSON 与 JSON → XML,也可以手动指定
  • ⚠️ 报出这次转换丢了什么:注释、处理指令、DOCTYPE 的条数
  • ⚠️ 检出混合内容(文字与子元素交错)并说明那一层结构已经丢失
  • ⚠️ 收尾说明这套转换天然有损、以及适合什么不适合什么
  • 属性写成 `@名字`,文本按有无其它键决定是否放进 `#text`
  • 同名子元素出现多次变数组,只出现一次保持标量
  • CDATA 与文本合并(JSON 里区分不了)
  • ⚠️ 标签名与属性名区分大小写 —— XML 就是这样,不像 HTML
  • ⚠️ 命名空间前缀原样保留,不做解析(并说明为什么)
  • ⚠️ 反过来时非法的键名跳过并报出来,不悄悄改写成合法名字
  • ⚠️ XML 比 HTML 严格:标签必须闭合、属性值必须加引号、未定义实体直接报错 —— 都给出出错位置
  • 全部在浏览器本地完成

使用方法

  1. 把 XML 或 JSON 粘进去,方向会自动识别(开头是 `<` 就按 XML 处理)
  2. 需要看约定就勾上「一并列出转换约定」
  3. 先看结果,再看「这次转换丢了什么」那一块

常见问题

为什么不把根元素展开掉?
因为那样反方向就做不了。展开之后 `<a><b>1</b></a>` 变成 `{"b":"1"}` —— 根元素的名字 `a` 没了。转回 XML 时该给它起个什么名字?只能猜一个 `<root>`,而那个名字不在你的数据里。这个工具是双向的,两个方向必须共用一套约定,所以根元素保留在外面。往返测试正是钉住这一点的:XML 转成 JSON 再转回来,语义必须一样。
「混合内容」是什么意思,为什么说它必然丢失?
指一个元素里文字与子元素交错出现:`<p>前面<b>粗</b>后面</p>`。这在 XML 里是完全合法的,而且顺序有意义(「后面」这两个字必须在那个 `<b>` 之后)。而 JSON 的对象是无序的键值对,表达不了「文字在第一和第二个子元素之间」这种位置。所以转过去之后文字会被拼成一段,位置信息没了。要保住它只能别转 —— 或者用能表达顺序的格式。这里至少会数出来有几个元素是这种情况,让人知道损失在哪。
为什么 `&nbsp;` 会报错?
因为 XML 只预定义了五个实体:`lt`、`gt`、`amp`、`quot`、`apos`。`&nbsp;` 是 HTML 的东西,在 XML 里属于未定义的实体,一份用了它的文档是不合法的。这里故意不宽容地把它解出来 —— 解出来会让一份有问题的文档看起来完全正常,而用户拿着「能用」的结果就不会去想为什么别的工具读不了它。要那个字符就写数字形式 `&#160;`。
XML 和 HTML 的解析差别有那么大吗?
很大。HTML 的设计目标是容错:标签不闭合、属性不加引号、大小写混用,浏览器都会尽力渲染。XML 的目标是严格:标签必须配对、属性值必须加引号、大小写敏感(`<Element>` 与 `<element>` 是两个东西)、未定义实体直接是错误。所以浏览器里那套 HTML 解析器不能拿来读 XML —— 它会把你文档里的问题悄悄修好,而你需要知道那些问题存在。
什么时候该用这个,什么时候不该?
该用:在服务之间搬运数据。比如一个接口只吐 XML,而你的代码更愿意处理 JSON;或者反过来要把一份配置喂给只认 XML 的老系统。不该用:编辑 XML 文档。如果那份 XML 里有混合内容、有注释、有命名空间,转一圈回来已经不是原来那份了,而差异不会报警。编辑 XML 请用能保住原格式的工具。

相关工具