XML 转 JSON 转换器

将 XML 转换为 JSON 格式

加载示例

XML 输入

JSON 输出

本地运行 · 粘贴密钥安全无忧
JSON 将显示在此处…

什么是 XML 转 JSON?

XML 转 JSON 是将数据从可扩展标记语言(XML)转换为 JavaScript 对象表示法(JSON)的过程。两种格式都能表示结构化的层级数据,但使用不同的语法和数据模型。XML 使用开闭标签和可选属性,而 JSON 使用键值对、数组和基本类型。将 XML 转换为 JSON,可以在 JSON 作为原生格式的环境中使用 XML 数据,例如 JavaScript 运行时、REST API 和 NoSQL 数据库。

转换并非总是一一对应的。XML 有一些在 JSON 中没有直接等价物的构造:属性、混合内容(文本与子元素交叉出现)、处理指令、注释、CDATA 节和命名空间声明。不同的转换库对这些构造的处理方式各异,这也是存在多种转换约定的原因。最常见的方案是对属性名添加 @ 前缀,当同一元素同时存在属性和文本内容时,将文本内容放入 #text 字段。

XML 转 JSON 是从 SOAP 迁移到 REST、使用旧式企业 API、或处理政府和金融数据(这些数据通常以 XML 格式提供)时的常见步骤。团队无需同时重写生产者和消费者,而是在边界层将 XML 负载转换为 JSON,再向下游传递。AWS API Gateway、Apache Camel 和 MuleSoft 均原生支持此模式。

XML input
<bookstore>
  <book category="fiction">
    <title lang="en">The Great Gatsby</title>
    <author>F. Scott Fitzgerald</author>
    <year>1925</year>
    <price>10.99</price>
  </book>
  <book category="non-fiction">
    <title lang="en">Sapiens</title>
    <author>Yuval Noah Harari</author>
    <year>2011</year>
    <price>14.99</price>
  </book>
</bookstore>
JSON output
{
  "bookstore": {
    "book": [
      {
        "@category": "fiction",
        "title": {
          "@lang": "en",
          "#text": "The Great Gatsby"
        },
        "author": "F. Scott Fitzgerald",
        "year": "1925",
        "price": "10.99"
      },
      {
        "@category": "non-fiction",
        "title": {
          "@lang": "en",
          "#text": "Sapiens"
        },
        "author": "Yuval Noah Harari",
        "year": "2011",
        "price": "14.99"
      }
    ]
  }
}

为什么使用在线 XML 转 JSON 转换器?

编写一次性转换脚本需要时间,尤其是当 XML 包含属性、命名空间或需要转换为 JSON 数组的重复元素时。基于浏览器的转换器能在数秒内输出 JSON 结果,让您快速检查结构后继续工作。

即时转换
粘贴 XML 即可立即获得 JSON 输出。无需安装库、编写脚本或配置构建工具。
🔒
隐私优先处理
整个转换过程在浏览器中通过 JavaScript 完成。您的 XML 数据不会离开本机,也不会上传到任何服务器。
🔀
支持属性和数组
属性映射为带 @ 前缀的键。重复的同级元素自动归组为 JSON 数组,遵循 Parker 或 BadgerFish 约定。
📋
无需账号
打开页面,粘贴 XML,复制 JSON 结果即可。无需注册,无需 API 密钥,无使用限制。

XML 转 JSON 使用场景

前端开发
将 XML API 响应转换为 JSON,以便在 React、Vue 或 Angular 组件中渲染数据,无需在客户端包中引入 XML 解析库。
后端工程
在 API 网关层将 SOAP 负载、RSS/Atom 订阅或 XML-RPC 响应转换为 JSON,再传递给期望接收 JSON 输入的微服务。
DevOps 与 CI/CD
将 XML 测试报告(JUnit、NUnit、xUnit)转换为 JSON,以便仪表盘、Slack 机器人或自定义 CI 通知管道摄取。
质量保证与测试
将转换后的 JSON 快照与预期输出进行对比,验证 XML 生产服务在不同版本间的响应结构是否发生变化。
数据工程
将政府门户、金融数据(FIX、FIXML)或医疗系统(HL7 CDA)导出的 XML 转换为 JSON,以便加载到 BigQuery、Snowflake 或 Elasticsearch 中。
学习数据格式
学习数据交换的学员可以将 XML 示例粘贴到转换器中,直观了解元素、属性和嵌套结构如何映射为 JSON 键、对象和数组。

XML 转 JSON 映射参考

XML 和 JSON 的数据模型不同。下表展示了在最常见约定下(属性使用 @,与属性共存的文本内容使用 #text),每种 XML 构造如何映射为对应的 JSON。混合内容和注释等构造没有标准的 JSON 表示形式。

XML 构造XML 示例JSON 等价形式
Element<name>text</name>"name": "text"
Nested elements<a><b>1</b></a>"a": { "b": "1" }
Attributes<el attr="v"/>"el": { "@attr": "v" }
Text + attributes<el a="1">text</el>"el": { "@a": "1", "#text": "text" }
Repeated elements<r><i>1</i><i>2</i></r>"r": { "i": ["1", "2"] }
Mixed content<p>A <b>B</b> C</p>Varies by convention
CDATA<![CDATA[raw]]>"#cdata": "raw" or flattened
Namespacesxmlns:prefix="uri"Prefix preserved or stripped
Empty element<el/>"el": null or ""
Comments<!-- note -->Discarded (no JSON equivalent)

XML 转 JSON 约定对比

目前没有统一的标准规定 XML 如何映射为 JSON。三种约定被广泛使用,各自在属性处理、数组检测和文本保留方面有不同的权衡。

BadgerFish
所有文本节点存入 $ 键,属性使用带 @ 前缀的键,命名空间以 @xmlns 条目保留。输出较冗长但无损:可以完整还原回 XML 而不丢失任何数据。
Parker
完全去除属性,将纯文本元素转换为裸值,重复元素变为数组。结果紧凑整洁,但具有破坏性:属性和命名空间信息会被丢弃。
GData(Google Data)
使用 $t 表示文本内容,不加前缀地将属性保留为顶级键。介于 BadgerFish 的冗长和 Parker 的简洁之间,曾被 Google API 历史性地采用。

代码示例

以下是在 JavaScript、Python、Go 和命令行中将 XML 转换为 JSON 的可运行示例。每个示例均处理了嵌套元素和重复同级标签。

JavaScript (browser)
// Using the DOMParser API to walk XML and build a JSON object
function xmlToJson(xml) {
  const parser = new DOMParser()
  const doc = parser.parseFromString(xml, 'application/xml')

  function nodeToObj(node) {
    const obj = {}
    // Handle attributes
    if (node.attributes) {
      for (const attr of node.attributes) {
        obj['@' + attr.name] = attr.value
      }
    }
    // Handle child nodes
    for (const child of node.childNodes) {
      if (child.nodeType === 3) { // text
        const text = child.textContent.trim()
        if (text) obj['#text'] = text
      } else if (child.nodeType === 1) { // element
        const key = child.nodeName
        const val = nodeToObj(child)
        if (obj[key]) {
          if (!Array.isArray(obj[key])) obj[key] = [obj[key]]
          obj[key].push(val)
        } else {
          obj[key] = val
        }
      }
    }
    // Simplify text-only nodes
    const keys = Object.keys(obj)
    if (keys.length === 1 && keys[0] === '#text') return obj['#text']
    return obj
  }

  return nodeToObj(doc.documentElement)
}

const xml = '<user><name>Alice</name><role>admin</role></user>'
console.log(JSON.stringify(xmlToJson(xml), null, 2))
// → { "name": "Alice", "role": "admin" }
Python
import xmltodict
import json

xml = """
<user>
  <name>Alice</name>
  <roles>
    <role>admin</role>
    <role>editor</role>
  </roles>
</user>
"""

# xmltodict converts XML to an OrderedDict
result = xmltodict.parse(xml)
print(json.dumps(result, indent=2))
# → {
# →   "user": {
# →     "name": "Alice",
# →     "roles": { "role": ["admin", "editor"] }
# →   }
# → }

# With the standard library (xml.etree.ElementTree)
import xml.etree.ElementTree as ET

def etree_to_dict(elem):
    d = {}
    if elem.attrib:
        d.update({f"@{k}": v for k, v in elem.attrib.items()})
    for child in elem:
        child_data = etree_to_dict(child)
        if child.tag in d:
            if not isinstance(d[child.tag], list):
                d[child.tag] = [d[child.tag]]
            d[child.tag].append(child_data)
        else:
            d[child.tag] = child_data
    if elem.text and elem.text.strip():
        if d:
            d["#text"] = elem.text.strip()
        else:
            return elem.text.strip()
    return d

root = ET.fromstring(xml)
print(json.dumps(etree_to_dict(root), indent=2))
Go
package main

import (
    "encoding/json"
    "encoding/xml"
    "fmt"
    "strings"
)

// For simple, known schemas — define a struct
type User struct {
    XMLName xml.Name `xml:"user"`
    Name    string   `xml:"name"`
    Roles   []string `xml:"roles>role"`
}

func main() {
    data := `<user><name>Alice</name><roles><role>admin</role><role>editor</role></roles></user>`
    var user User
    xml.NewDecoder(strings.NewReader(data)).Decode(&user)

    out, _ := json.MarshalIndent(user, "", "  ")
    fmt.Println(string(out))
    // → { "Name": "Alice", "Roles": ["admin", "editor"] }
}
CLI (xmllint + jq / yq)
# Using xq (part of yq, a jq wrapper for XML)
# Install: pip install yq  OR  brew install yq
echo '<user><name>Alice</name></user>' | xq .
# → { "user": { "name": "Alice" } }

# Using xmlstarlet + jq
xmlstarlet sel -t -v '//name' input.xml | jq -R '{ name: . }'

# Node.js one-liner with xml2js
echo '<a><b>1</b></a>' | node -e "
  const {parseString} = require('xml2js');
  let d=''; process.stdin.on('data',c=>d+=c);
  process.stdin.on('end',()=>parseString(d,(e,r)=>console.log(JSON.stringify(r,null,2))))
"

常见问题

XML 转 JSON 是无损转换吗?
不一定。XML 属性、注释、处理指令和命名空间声明在 JSON 中没有直接等价物。大多数转换器通过 @ 前缀约定保留属性,但注释和处理指令会被丢弃。如需完全可逆的往返转换,请使用 BadgerFish 等无损约定。
XML 属性在 JSON 中如何表示?
最常见的方式是在属性名前添加 @ 前缀。例如,<book id="1"> 转换为 {"@id": "1"}。部分转换器改用嵌套的 "_attributes" 对象。具体约定取决于所使用的库。
转换器如何处理重复的 XML 元素?
当某个元素在同一父节点下出现多次时,转换器会将它们归组为一个 JSON 数组。例如,两个 item 同级元素变为 {"item": ["a", "b"]}。单个 item 元素保持为普通字符串值,除非启用了强制数组模式。
可以将 JSON 转回 XML 吗?
可以,但结果取决于原始转换所使用的约定。如果属性通过 @ 前缀保留,JSON 转 XML 工具可以还原它们。如果原始转换使用了 Parker 约定(会丢弃属性),则这些信息已永久丢失。ToolDeck 也提供 JSON 转 XML 工具用于反向转换。
转换过程中 XML 命名空间如何处理?
命名空间的处理方式因库而异。部分转换器在键名中保留前缀(例如 "ns:element"),另一些将 xmlns 声明映射为独立字段,还有一些直接去除命名空间。请检查输出结果,确认您的 XML 命名空间行为是否符合预期。
XML 转 JSON 有统一标准吗?
目前没有正式的 W3C 或 IETF 标准。最接近的参考是 BadgerFish 约定、Parker 约定和 OASIS XSLT 到 JSON 的映射规范。实际上每个库都实现了自己的规则,这就是为什么同一段 XML 在不同工具中可能产生略有差异的 JSON。
如何处理大型 XML 文件?
浏览器端转换器适用于几兆字节以内的文件。对于更大的文件(10 MB 以上),请使用流式解析器,例如 Python 的 iterparse(xml.etree.ElementTree)或 Node.js 的 xml-stream。这些工具以增量方式处理文档,无需将整棵树加载到内存中。