Skip to content

JSON 转 XML 转换器

粘贴 JSON 即时获得 XML。在浏览器端转换对象、数组和 @_ 属性 — 数据不上传。免费、隐私保护,无需注册。

无追踪 浏览器中运行 免费
选项 · 2 空格 · JSON → XML
缩进
0 字符
XML 输出
0
已审核 XML 1.0 格式良好性、@_/#text 约定正确性以及根规范化准确性 — Go Tools 工程团队 · 2026年5月29日

什么是 JSON 转 XML 转换,它是如何工作的?

JSON(JavaScript 对象表示法)和 XML(可扩展标记语言)都是结构化数据格式,但它们的模型根本不同:JSON 是一棵由对象、数组、字符串、数字、布尔值和 null 值组成的树,没有属性或文档根约束的概念;XML 是一棵元素树,元素可以携带属性和文本内容,且文档必须有且仅有一个根元素。从 JSON 转换为 XML 需要一套约定来弥合这种不匹配。

本工具使用最广泛采用的约定 — 与 fast-xml-parser(Node.js)、xmltodict(Python)和 JAXB(Java)使用的相同 — 并以反向方式应用:

**1. 根元素规范化。** JSON 与 XML 最重要的区别是根约束。JSON 没有根的概念;XML 要求有且仅有一个根。转换器自动处理四种情况。单键对象使用该键作为 XML 根:{ "config": {...} } → ...。多键对象包裹在 中:{ "a": 1, "b": 2 } → 12。顶层数组包装为 ...。原始值包装为 value

**2. @_ 前缀 → XML 属性。** 带 @_ 前缀的 JSON 键变为包含元素上的 XML 属性。{ "element": { "@_id": "42", "@_class": "primary" } } 生成 。这个前缀是规范约定 — 没有合法的 XML 元素名称以 @ 开头,因此与子元素名称永远不会冲突。

**3. #text → 元素文本内容。** 当元素同时需要属性和文本内容时,文本存储在 #text 键下:{ "price": { "@_currency": "USD", "#text": "29.99" } } → 29.99。只有文本内容(无 @_ 键)的元素直接转换为纯文本元素,无需此间接方式。

**4. 数组 → 重复的同名兄弟元素。** XML 允许多个同名子元素;JSON 使用数组表示有序列表。键下的 JSON 数组生成复用该键名的重复子元素:{ "items": ["a", "b"] } 生成 ab(两个 元素作为父元素下的兄弟元素)。当整个 JSON 输入为顶层数组时,添加 包装,每个元素成为 子元素 — 是仅在该情况下使用的固定备用名称。

**5. 与 XML 转 JSON 对称。** 此处使用的 @_ 和 #text 约定与配套工具 XML 转 JSON 转换器使用的完全相同。这意味着 JSON → XML → JSON 的往返转换可以保留属性、文本内容和元素结构 — 前提是输入 JSON 遵循 @_/#text 约定。

**何时需要将 JSON 转换为 XML?** 最常见的场景是:(1) 向需要 XML 请求体的遗留 SOAP 或 XML 格式 Web 服务发送数据;(2) 从 JSON 数据生成 XML 配置文件(Spring、Maven、Ant、Android 资源);(3) 从 JSON 内容数据生成 sitemap.xml 或 RSS Feed XML;(4) 与消费 XML 的企业系统(ERP、CRM、EDI)互操作;(5) 以编程方式从 JSON 数据生成 SVG 或其他基于 XML 的图形格式。生成 XML 后如需格式化和验证,请使用 XML 格式化工具

// Convert JSON to XML in Node.js using fast-xml-parser
import { XMLBuilder } from 'fast-xml-parser';

const data = {
  catalog: {
    product: {
      '@_id': 'P01',
      '@_category': 'electronics',
      name: 'Wireless Headphones',
      price: {
        '@_currency': 'USD',
        '#text': '79.99'
      }
    }
  }
};

const builder = new XMLBuilder({
  attributeNamePrefix: '@_',   // @_ keys become XML attributes
  textNodeName: '#text',       // #text key becomes element text content
  ignoreAttributes: false,     // process @_ attribute keys
  format: true,                // pretty-print with indentation
  indentBy: '  ',              // 2-space indent
});

const xml = builder.build(data);
console.log(xml);
// <catalog>
//   <product id="P01" category="electronics">
//     <name>Wireless Headphones</name>
//     <price currency="USD">79.99</price>
//   </product>
// </catalog>

核心功能

实时转换

输入或粘贴 JSON 时,XML 输出即时更新 — 无需点击「转换」按钮。大型输入(>200KB)自动切换为手动模式以保持浏览器响应。

自动根元素规范化

XML 要求有且仅有一个根元素。单键对象使用其键作为根;多键对象包裹在 中;顶层数组变为 ...;原始值变为 value — 始终输出有效 XML。

@_ 属性与 #text 约定

带 @_ 前缀的键变为 XML 属性;#text 键变为元素文本内容。与 fast-xml-parser 和 xmltodict 约定一致,使输出与配套 XML 转 JSON 转换器完全对称。

数组变为重复元素

键下的 JSON 数组生成复用该键名的重复子元素 — 不进行单数化处理。{ "items": [1, 2, 3] } 生成三个 兄弟元素。顶层数组输入包装为 ...,使用 作为固定字面量名称。

100% 浏览器端隐私保护

所有转换均在浏览器中通过 JavaScript 本地运行。你的 JSON(包括凭证、内部配置和敏感载荷)不会被发送到任何服务器,不会被记录,也不会被存储。

与 XML 转 JSON 对称往返

@_ 和 #text 约定与配套 XML 转 JSON 转换器共享。JSON → XML → JSON 的往返转换能忠实保留属性、文本内容和嵌套结构。

示例

API 响应对象

{"user":{"id":42,"name":"Alice Kim","email":"alice@example.com","role":"admin","address":{"city":"Seoul","country":"KR"}}}

一个单键 JSON 对象,顶层键作为 XML 根元素。嵌套的 address 对象生成一个包含 子元素的

子元素。由于外层对象恰好只有一个键("user"),不添加额外包装 — "user" 本身即为根元素。数字 42 直接成为文本内容:42

顶层数组

[{"id":1,"name":"Widget A","price":9.99},{"id":2,"name":"Widget B","price":14.99},{"id":3,"name":"Widget C","price":4.49}]

当整个输入是 JSON 数组(而非包裹在对象中)时,转换器生成 ...。每个数组元素变为一个 子元素 — "item" 是专门用于顶层数组的固定字面量包装名称。这是 出现的唯一情况;对象键下的数组会复用该键的名称作为每个元素的标签名。

带属性和文本内容的对象

{"catalog":{"product":{"@_id":"P01","@_category":"electronics","name":"Wireless Headphones","price":{"@_currency":"USD","#text":"79.99"}}}}

带 @_ 前缀的键变为元素上的 XML 属性:@_id 变为 id="P01",@_category 变为 元素上的 category="electronics"。#text 键变为元素的文本内容 — 因此 price 对象生成 79.99。这与 XML 转 JSON 转换器完全对称往返,两者使用相同的 @_ 和 #text 约定。

使用方法

  1. 1

    粘贴 JSON 数据

    在上方输入框中输入或粘贴 JSON 数据。也可以点击「加载示例」试用示例 — API 响应对象、数组载荷,或使用 @_ 属性和 #text 的对象。

  2. 2

    查看实时 XML 输出

    XML 即时显示在输出面板中。单键对象使用其键作为根元素;多键对象包裹在 中;带 @_ 前缀的键变为属性;数组变为重复子元素。按需调整缩进(2 或 4 空格)。

  3. 3

    复制或下载

    点击「复制」将 XML 复制到剪贴板,或点击「下载」将其保存为 .xml 文件。如需验证或重新格式化结果,请将其粘贴到 XML 格式化工具中。

常见转换陷阱

多键对象得到意外的 包装

如果顶层 JSON 有多个键,输出会将它们全部包裹在 中。这是正确的 XML(XML 要求单根元素),但可能与目标模式不匹配。请将 JSON 重塑为单键对象以控制根元素名称。

✗ 错误
// Input: { "status": 200, "data": { "id": 1 } }
// Output: <root><status>200</status><data><id>1</id></data></root>
// Root is <root> — may not match your schema
✓ 正确
// Wrap in a named key to control the root element
// Input: { "response": { "status": 200, "data": { "id": 1 } } }
// Output: <response><status>200</status><data><id>1</id></data></response>

顶层数组得到 包装

顶层 JSON 数组没有元素名称,因此被包装为 ...。如果需要有意义的标签名,请先将数组包裹在命名对象中。

✗ 错误
// Input: [{ "id": 1 }, { "id": 2 }]
// Output: <root><item><id>1</id></item><item><id>2</id></item></root>
// Tag names are generic
✓ 正确
// Wrap in a named key for meaningful tag names
// Input: { "products": [{ "id": 1 }, { "id": 2 }] }
// Output: <root><products><id>1</id></products><products><id>2</id></products></root>
// Each array element reuses the key name "products" as its tag

属性键缺少 @_ 前缀

要生成 XML 属性,JSON 键必须带 @_ 前缀。没有前缀时,该键被视为子元素而非属性。

✗ 错误
// Input: { "tag": { "id": "42", "name": "Alice" } }
// Output: <tag><id>42</id><name>Alice</name></tag>  ← id is a child element
✓ 正确
// Use @_ prefix for attributes
// Input: { "tag": { "@_id": "42", "name": "Alice" } }
// Output: <tag id="42"><name>Alice</name></tag>  ← id is an attribute

同时有属性和文本的元素 — 缺少 #text

如果要让元素同时拥有 XML 属性和文本内容,必须使用 #text 键存储文本。没有它,文本无处可放,元素将为空或产生错误。

✗ 错误
// Input: { "price": { "@_currency": "USD", "value": "29.99" } }
// Output: <price currency="USD"><value>29.99</value></price>
// Text is a child element, not text content
✓ 正确
// Use #text for element text content
// Input: { "price": { "@_currency": "USD", "#text": "29.99" } }
// Output: <price currency="USD">29.99</price>  ← text content

JSON 键包含 XML 无效字符

XML 元素名称不能以数字开头,不能包含空格、冒号(除命名空间前缀外)或大多数特殊字符。如果 JSON 键包含这些字符,输出的 XML 将格式不良。请在转换前重命名有问题的键,或在后处理步骤中进行净化。

✗ 错误
// JSON key starts with digit — invalid XML element name
// Input: { "1stItem": "value" }
// Output: <1stItem>value</1stItem>  ← invalid XML
✓ 正确
// Use a valid XML element name
// Input: { "firstItem": "value" }
// Output: <firstItem>value</firstItem>  ← valid XML

值中的特殊字符未转义

XML 文本内容不得包含原始的 <、>、& 或 " 字符 — 必须转义为 <、>、& 和 "。转换器会自动转义元素文本内容和属性值中的这些字符。如果下游处理对其进行了二次转义,请确认你的 XML 解析器消费的是原始 XML 字节,而非对已转义内容再次转义。

✗ 错误
// JSON: { "query": "name = 'Alice' & role = 'admin'" }
// Converter outputs: <query>name = 'Alice' &amp; role = 'admin'</query>
// If double-processed: &amp;amp; — consumer is re-escaping
✓ 正确
// Converter output is correct — consume it as XML, not as a raw string
// <query>name = 'Alice' &amp; role = 'admin'</query>
// XML parser decodes to: name = 'Alice' & role = 'admin'

常见使用场景

调用 SOAP 和遗留 XML Web 服务
在应用中构建 JSON 载荷,转换为 XML,然后将其 POST 到 SOAP 端点。这避免了手工拼接 XML 字符串,让你可以以原生 JSON 结构处理数据,直到需要为遗留服务序列化的最后一刻。
生成 XML 配置文件
Spring、Maven、Ant、Tomcat 和 Android 都使用 XML 配置格式。以 JSON 生成或转换配置数据(更易于 diff 和版本控制),再转换为 XML 用于部署。
生成 Sitemap 和 RSS Feed XML
内容管理系统和静态网站生成器通常以 JSON 形式存储页面元数据。将该元数据转换为 sitemap.xml 或 RSS Feed XML,提交给搜索引擎或将内容分发到 Feed 阅读器。
企业数据集成(EDI / ERP / CRM)
ERP 系统(SAP、Oracle)、CRM 平台和 EDI 网络通常以 XML 格式交换数据。将现代 REST API 的 JSON 导出转换为 XML,无需构建自定义 XML 序列化器即可对接这些系统。
Android 资源文件
Android 字符串资源、布局约束和 Manifest 条目都是 XML。以编程方式从 JSON 数据源生成或更新资源文件,并转换为 Android 构建系统所需的 XML 格式。
SVG 和矢量图形生成
SVG 是 XML。以 JSON 数据形式构建 SVG 结构 — 路径、形状、颜色、变换 — 然后转换为 XML 以生成适用于 Web、印刷或矢量编辑工具的有效 SVG 文件。

技术细节

符合 RFC 8259 的 JSON 解析
JSON 输入使用浏览器原生的 JSON.parse() 解析,完全符合 RFC 8259 标准。提供准确的语法错误信息(尽力提供位置信息:行号和列号),并处理所有 JSON 数据类型:字符串、数字、布尔值、null、数组和对象。
自定义递归 JSON 转 XML 序列化器
解析后,自定义递归序列化器遍历 JSON 树。以 @_ 开头的对象键作为父元素上的 XML 属性输出。#text 键作为元素的文本内容输出。普通对象键变为子元素。数组值生成重复的同名兄弟元素。文本内容和属性值中的特殊字符(<、>、&、"、')转义为其 XML 实体引用。
根元素规范化
由于 XML 要求有且仅有一个根元素,序列化器在构建文档前应用根元素规范化:单键对象使用该键作为根;多键对象和顶层数组接收合成的 包装。这确保无论输入形状如何,输出始终是格式良好的 XML。
100% 浏览器端 — 不上传,无服务器
所有处理均在浏览器的 JavaScript 引擎中运行。数据在任何时候都不会通过网络传输。超过 200KB 的输入会自动从实时模式切换到手动模式(需要显式点击「转换」),以保持浏览器响应,防止繁重序列化时主线程阻塞。

最佳实践

使用单键对象控制根元素
生成有意义 XML 最简洁的方式是确保顶层 JSON 是一个单键对象,其键就是所需的根元素名称。将多键数据包裹在一个命名键下,可以得到语义明确的根元素,而非通用的 包装。
对属性密集型 XML 使用 @_ 和 #text
如果目标 XML 模式大量使用属性(配置文件、SVG 和 SOAP 信封中很常见),请在转换前将 JSON 中相应字段改用带 @_ 前缀的键和 #text。生成的 XML 将与目标模式完全匹配,无需后处理。
将数组包裹在命名对象中以获得有意义的标签名
顶层数组生成通用的 ... 模式,其中 是固定字面量名称。将数组包裹在命名键下 — { "products": [...] } — 会生成重复的 元素(键名用于每个数组元素)置于 包装下。这给出了领域相关的标签名,对于需要被模式解析或验证的 XML 几乎总是更好的选择。
使用 XML 格式化工具验证输出
转换后,将 XML 输出粘贴到 XML 格式化工具中,验证格式良好性、检查缩进,并在将 XML 发送给下游服务或提交到版本控制前识别任何结构问题。
转换前净化 JSON 键
XML 元素名称必须以字母或下划线开头,且不得包含空格或大多数特殊字符。如果 JSON 键来自外部来源(数据库列名、API 字段名或用户输入),请在转换前审核其 XML 名称有效性,以避免生成格式不良的输出。

常见问题

使用此工具时,我的 JSON 数据会被上传到服务器吗?
不会。所有转换完全在浏览器中通过 JavaScript 完成。你的 JSON 数据不会通过网络传输,不会存储在任何服务器上,也不会被记录或分析。因此,即使 JSON 载荷包含 API 凭证、数据库配置、内部服务数据或其他敏感内容,使用本工具也是安全的。你可以通过打开浏览器的「网络」标签来验证 — 粘贴或转换 JSON 时不会触发任何请求。
工具如何决定 XML 根元素是什么?
XML 要求有且仅有一个根元素;JSON 没有此限制。转换器应用以下规则:(1) 单键对象使用该键作为根元素名称 — { "user": { ... } } 变为 ...。(2) 多键对象(顶层有两个或更多键)被包裹在 元素中,所有键成为单一根元素的子元素。(3) 顶层数组被包装为 ...,每个数组元素成为一个 子元素。(4) 顶层的原始值(字符串、数字、布尔值、null)变为 value。这些规则确保输出始终是有且仅有一个根元素的格式良好 XML。
为什么多键 JSON 对象会被包裹在 中?
XML 是一种严格要求单根元素的文档格式 — 一个有效的 XML 文档必须有且仅有一个顶层元素。JSON 对象可以有任意数量的顶层键,因此当 JSON 有多个顶层键(如 { "status": 200, "data": {...}, "meta": {...} })时,没有单一的键可用作根元素。包裹在 中是最安全且最可预测的约定。如果你想使用不同的根元素名称,请在转换前将 JSON 重塑为单键对象 — 例如 { "response": { "status": 200, "data": {...} } }。
顶层 JSON 数组如何转换为 XML?
顶层数组被包装为 ......。每个数组元素成为一个 子元素 — "item" 是仅用于顶层数组的固定字面量名称。这与嵌套在对象键下的数组不同:如果写成 { "products": [...] },每个数组元素变为一个 子元素(复用键名),而非 。如果需要顶层数组使用自定义标签名,请先将其包裹在命名对象中:{ "products": [...] } 会生成重复的 元素。
如何将 JSON 键转换为 XML 属性?
在键前加上 @_ 前缀,转换器会将其作为 XML 属性而非子元素输出。例如,{ "tag": { "@_id": "42", "@_lang": "en", "#text": "Hello" } } 生成 Hello。@_ 前缀约定与 fast-xml-parser(Node.js)和 xmltodict(Python)使用的相同,使输出能与这些库一致地往返。这也是配套工具 XML 转 JSON 转换器使用的约定。
#text 键有什么用?
当元素既需要 XML 属性又需要文本内容时,无法简单地将文本映射到子元素 — 它必须是元素自身的文本节点。JSON 中的 #text 键就变为该文本内容。示例:{ "price": { "@_currency": "USD", "#text": "29.99" } } 生成 29.99。如果对象只有 #text 键而没有 @_ 键,仍然生成普通文本元素:{ "note": { "#text": "hello" } } 变为 hello
缩进会影响 XML 结构吗?
不会。缩进纯粹是外观上的 — 它改变 XML 的格式以提高人类可读性,但不影响元素结构、属性值或文本内容。选择 2 空格可获得紧凑输出,4 空格可获得更易读的输出。两者生成语义上完全相同的 XML。大多数 XML 解析器将元素之间的纯空白文本节点视为可忽略的空白,因此缩进和压缩的 XML 在解析目的上是等价的。
嵌套在对象内的 JSON 数组如何转换为 XML?
键下的 JSON 数组值生成重复的同名子元素,每个元素复用该键名。例如,{ "items": [1, 2, 3] } 生成三个 兄弟元素 — 而非 。类似地,{ "products": [{"name":"A"},{"name":"B"}] } 生成两个 元素,每个包含一个 子元素。键名原样用于每个数组元素;不进行单数化处理。字面量名称 仅在整个 JSON 输入为顶层数组时出现(见上文),此时 是固定的备用包装名称。
如何将 XML 转换回 JSON?
使用配套工具 XML 转 JSON 转换器。它以相同的 @_ 和 #text 约定进行反向转换:XML 属性变为带 @_ 前缀的 JSON 键,与属性并存的元素文本内容变为 #text 键,重复的同名兄弟元素变为 JSON 数组。两个工具在往返使用场景中完全对称。
可以验证或格式化 XML 输出吗?
可以 — 将 XML 输出粘贴到 XML 格式化工具中,即可验证格式良好性、调整缩进或进行压缩。一旦本转换器生成了 XML,XML 格式化工具就是检查和完善该 XML 的合适工具。
JSON 输入有文件大小限制吗?
没有硬性限制,但超过 200KB 的输入会自动从实时转换切换到手动模式。在手动模式下,会出现「转换」按钮,只有点击时才执行转换 — 这在繁重序列化时保持浏览器响应。对于非常大的 JSON 文件(多兆字节),建议使用命令行工具以获得更好性能:node -e "const {XMLBuilder}=require('fast-xml-parser');console.log(new XMLBuilder({attributeNamePrefix:'@_'}).build(JSON.parse(require('fs').readFileSync('in.json','utf8'))))" 或等效的 Python xmltodict 脚本。
支持哪些 JSON 类型?
支持全部六种 JSON 类型。对象变为带子元素的 XML 元素。数组变为重复的同名兄弟元素。字符串、数字、布尔值和 null 变为元素文本内容。布尔值和 null 以其字面量字符串表示序列化:true、false 以及 null 对应空内容。不应用类型强制转换 — 数字以其在 JSON 中出现的形式原样写入 XML 文本内容,保留小数和精度。