← 全部文章

JSON 转 XML:根元素、数组与属性映射

把 JSON 转成 XML:选根元素、把 @ 前缀键映射为属性、把数组转成重复元素、做转义 —— 用 JS、Python 和在线工具。

把 JSON 转换为 XML 是一个有损映射的反向操作,这意味着你必须做出 JSON 从不强迫你做的选择:根元素是什么?这个键应该变成属性还是子元素?JSON 数组怎么变成重复的 XML 标签?本指南覆盖 JSON 转 XML 的约定 —— 根元素、数组、属性与转义 —— 在 JavaScript、Python 与浏览器中。

选择根元素

XML 要求有且只有一个根元素;JSON 没有这条规则。所以第一个决定是用什么把所有内容包起来。如果你的 JSON 是只有一个顶层键的对象,那个键就是天然的根:

{ "note": { "to": "Ada", "from": "Bob" } }

<note>
  <to>Ada</to>
  <from>Bob</from>
</note>

如果 JSON 有多个顶层键(或者是数组),就没有单一的根,转换器会把所有内容包在一个合成的元素里,例如 <root>

{ "to": "Ada", "from": "Bob" }

<root>
  <to>Ada</to>
  <from>Bob</from>
</root>

@-前缀键变属性

为了与 XML 转 JSON 的约定能完整往返,以 @ 开头的键会被输出为属性而不是子元素,而 #text 键则成为该元素的文本内容:

{
  "price": { "@currency": "USD", "#text": "9.99" }
}

<price currency="USD">9.99</price>

如果不使用这个约定,每个值都会变成子元素 —— 也是合法的,只是更啰嗦。这套 @/#text 约定,才让 XML → JSON → XML 能做到无损往返。

数组变成重复的元素

JSON 数组不会变成有多个值的单一元素 —— 而是变成同名元素的多次重复,因为这就是 XML 表示列表的方式:

{ "tags": { "tag": ["a", "b", "c"] } }

<tags>
  <tag>a</tag>
  <tag>b</tag>
  <tag>c</tag>
</tags>

一个微妙的后果是:顶层的对象数组不能作为根(那会产生多个根元素),所以必须包起来 —— 常见的是用 <root> 包住重复的 <item> 元素。

没有清晰映射的值

  • 布尔与数字 —— XML 没有类型,所以 true42 都写为文本 true42
  • null —— 通常是空/自闭合的元素:<middleName/>
  • 不是合法元素名的键 —— 名字不能以数字开头或含空格。"1st place" 不是合法的标签,必须先做清洗,否则会得到非法的 XML。

转义与声明

文本和属性值必须转义 &<>(属性里还有 ")。转换器还应在前面加上 XML 声明,使输出成为完整文档:

<?xml version="1.0" encoding="UTF-8"?>
<message>B &amp; C are &lt; D</message>

对应 XSD 或产出 xmlns

如果你的下游会按一份 XSD(XML Schema)来校验 XML,转换除了「键→元素」的映射之外,还需要做几件额外的事:

  • 元素顺序很重要。 XML 的元素属性(按规范)无序,但子元素是有序的,多数 XSD 通过 xsd:sequence 强制这一顺序。请按 Schema 期望的顺序输出子元素,而不是按对象键的遍历顺序,否则校验会失败。
  • 命名空间映射。xmlns 声明以 @xmlns 属性的形式重建在根上,并把带前缀的名字反映回 XML("soap:Envelope"<soap:Envelope>)。丢失命名空间的转换器会产出无法通过任何依赖命名空间的 XSD 校验的 XML。
  • 感知类型的值。 XML 没有原生类型,所以带 xsd:intxsd:date 的 XSD 只是检查文本内容是否符合。请把 JSON 值格式化为 XSD 模式期望的文本(ISO 日期、整数字符串等)。

用代码把 JSON 转为 XML

// JavaScript —— 一个小型递归构建器,或者库:
import { XMLBuilder } from 'fast-xml-parser';
const builder = new XMLBuilder({ ignoreAttributes: false, attributeNamePrefix: '@' });
const xml = builder.build(jsonObject);

# Python —— dicttoxml,或用 xml.etree.ElementTree 自建
from dicttoxml import dicttoxml
xml_bytes = dicttoxml({"note": {"to": "Ada"}}, attr_type=False)

在线把 JSON 转为 XML

把 JSON 贴进 JSON ⇄ XML 转换器 并点击 To XML。它会挑选一个合理的根、把 @ 键映射为属性、把数组展开为重复元素,并转义特殊字符 —— 全程在你的浏览器里。如果 JSON 有语法错误,会先尝试修复;你也可以用 JSON Fix 先清理。

常见问题

怎样把 JSON 转为 XML?

选一个根元素(单一顶层键,或者合成的 <root>),然后递归地把键变成子元素、把 @-前缀键变成属性、把数组展开成重复元素 —— 同时在文本中转义 &<>

JSON 数组在 XML 中如何呈现?

每个数组项都变成一个独立的、同名标签的元素,因为 XML 用「元素的重复」来表示列表,而不是单个多值节点。

怎样让一个 JSON 值变成 XML 属性?

给键名加上 @ 前缀(例如 "@id"),并把元素的文本放在 #text 下。这与标准的 XML 转 JSON 约定一致,因此转换可往返。

如果 JSON 键不是合法的 XML 元素名怎么办?

XML 标签名不能以数字开头或含空格,所以像 "1st place" 这样的键必须先清洗(例如改为 _1st_place),否则输出不是格式良好的 XML。

相关工具与指南