JSON 转 XML 实战:键变标签,数组变重复元素,对接 SOAP 与老系统
讲清 JSON 转 XML 的核心规则:对象键变标签、数组变重复元素、嵌套对象变子元素,以及根节点、属性与子元素之分、特殊字符转义,帮你把数据喂给 SOAP 接口和需要 XML 的老系统。
JSON 转 XML 实战:键变标签,数组变重复元素,对接 SOAP 与老系统
我维护过一个内部全是 REST/JSON 的服务,偏偏有个二十年老的合作方只收 SOAP。每次发请求前都要把一段 JSON 手工敲成 XML,漏个转义、忘了根节点,对面就回一个面目全非的报错。后来我把这套规则梳理清楚,转换这件事其实只有几条死规矩。这篇就把这几条讲透:键怎么变标签,数组怎么变重复元素,属性和子元素怎么分,转义为什么不能省。
对象的键变成标签,嵌套对象变成子元素
JSON 转 XML 最基础的一条:对象的每个 key 变成一个元素名,key 对应的值变成这个元素的内容。如果值还是一个对象,那它就递归地变成一组子元素,嵌套多深就生成多深。
举个具体的:{ "book": { "title": "X", "author": { "name": "Lei" } } }。最外层 key book 变成 <book>,里面的 title 变成 <title>X</title>,而 author 因为值是对象,就继续展开成 <author><name>Lei</name></author>,整段结果是 <book><title>X</title><author><name>Lei</name></author></book>。你写 JSON 时的层级结构,原封不动地搬到了 XML 的标签嵌套里。
数组没有原生对应,只能重复同一个元素
XML 里没有数组这个概念,所以处理列表的标准写法是:把承载列表的那个元素,按条目数重复一遍。{ "list": { "item": ["a", "b"] } } 转出来是 <list><item>a</item><item>b</item></list>,key item 是元素名,数组里每个值都得到自己的一对 <item> 标签。
这正是 RSS 里 <item>、Atom 里 <entry> 的写法,所以从 JSON 列表生成订阅源时,把文章数组包在 { "channel": { "item": [...] } } 下面就天然合规。空数组 [] 则收敛成一个自闭合的 <list/>。
一个文档只能有一个根节点
合法的 XML 文档必须有且仅有一个根元素,这是规范的硬性规定,不是工具的脾气。当你的 JSON 只有一个顶层 key,这个 key 自动当根:{ "note": {...} } 直接变 <note>…</note>。
但如果顶层有零个或两个以上的 key,比如 { "a": 1, "b": 2 },或者顶层干脆是个数组、是个标量,那就没有天然的根可用,需要你指定一个包裹元素名(默认 root)把内容整体套住,输出才是能被解析的合法 XML。对接 Spring beans、老的 .NET app.config 时,这个根名通常就是 beans 或 configuration。
属性还是子元素:用前缀约定区分
同一份数据,既可以写成子元素 <book><id>7</id></book>,也可以写成属性 <book id="7">。区分靠一个前缀约定:以 @ 开头的 key 当属性,其余 key 当子元素。{ "book": { "@id": "7", "title": "X" } } 产出 <book id="7"><title>X</title></book>。
要注意属性只能放标量值,因为 XML 属性里不能再嵌套标记。如果你把 @meta 指向一个对象,它会被直接跳过,而不是吐出非法的 attr="[object Object]"。需要文本节点和属性并存时,用 #text 这个 key 表示元素紧挨属性的文本内容,这在写 Android 资源时特别顺手:{ "string": { "@name": "app_title", "#text": "Toolora" } } 就是 <string name="app_title">Toolora</string>。
转义是底线,不是可选项
业务字符串里出现 &、<、> 是常事,一个订单备注写着 Q&A,一个标题叫 Tips & Tricks,直接塞进 XML 就把文档撑破了,严重时还是注入口子。文本内容要转义 &、<、>;属性值还要额外转义 " 和 '。
下面是一段真实输入输出。JSON:
{ "order": { "@id": "7", "note": "1 < 2 & buy now", "items": { "sku": ["A1", "B2"] } } }
转出的 XML:
<order id="7">
<note>1 < 2 & buy now</note>
<items>
<sku>A1</sku>
<sku>B2</sku>
</items>
</order>
留意三点:@id 落成了属性,note 里的 < 和 & 被转成了实体,sku 数组重复成了两对标签。这段直接粘进 <soap:Body> 也好,塞进配置文件也好,对面解析器都不会噎住。元素名本身也会被清洗:带空格或冒号的 key 里非法字符变成 _,以数字或 xml 开头的名字补一个前导下划线,所以不规范的 key 也产不出非法标记。
在浏览器里跑完整条链路
上面这些规则,在 /zh/t/json-to-xml/ 里都能直接试:粘 JSON、调根名、选缩进、改前缀、开关声明头,输出可以一键复制或下载 .xml,整个过程纯浏览器本地,报文不出标签页。如果你手上是反方向的活,拿到一坨 XML 想用 JSON 工具链批量改,先走 /zh/t/xml-to-json/ 解析成对象,改完再回这里转回来。两边保持属性前缀和 #text key 一致,元素结构、属性、文本就能完整往返。
把规则记牢,JSON 转 XML 就从"每次都要试错"变成"心里有底"。键变标签、数组变重复元素、单根、前缀分属性、转义兜底,这五条吃透,对接 SOAP、生成 RSS、改老配置,基本都不会再被格式问题绊住。
Made by Toolora · Updated 2026-06-13