
XML转JSON:开发者实用指南
📷 Pixabay / PexelsXML转JSON:开发者实用指南
XML感觉像是上个时代的产物,但你仍然每天都会在API、配置文件和数据源中遇到它。这里介绍如何不失去理智地完成转换。
每隔几年,开发者社区就会兴奋地宣布XML已死。然后你接到第一个企业集成合同,或者拉取RSS订阅,或者查看Android布局文件,或者有人递给你一个小说大小的SOAP API响应——XML就在那里。依然非常健在。
本指南不是关于XML是好是坏的讨论。而是关于一个实际问题:当你有XML数据并需要JSON时——无论是为了输入现代API、在JavaScript中解析,还是只是让它可读——该怎么办。让我们开始吧。
2026年你仍然会遇到XML的原因
XML是1990年代末和2000年代占主导地位的数据交换格式。JSON在2010年代基本上取代了它的Web API地位,但XML从未消失——它只是移居到了已经根深蒂固的地方。
你仍然会定期遇到XML的地方:
RSS和Atom订阅。 每个主要新闻网站、播客平台和博客仍然以XML格式发布RSS订阅。如果你在构建任何内容聚合器、新闻阅读器或播客应用,你就在处理XML。
SOAP Web服务。 很多企业和政府系统使用基于XML的SOAP API。银行集成、保险系统、医疗API、运输承运商——SOAP在B2B软件中无处不在。
Maven和Gradle(Java/Kotlin构建工具)。 pom.xml文件。如果你碰到任何JVM项目,就会碰到XML。Android的AndroidManifest.xml和布局文件也是XML。
Microsoft Office格式。 DOCX、XLSX、PPTX是包含XML的ZIP压缩包。以编程方式生成或解析文档通常意味着在底层处理XML。
SVG。 可缩放矢量图形是XML。如果你以编程方式处理矢量图像,就进入了XML领域。
Salesforce。 Salesforce的SOQL和Bulk API v1都输出XML。
规律很明显:现代Web开发严重倾向于JSON,但一旦接触企业集成、数据源或较旧的生态系统,XML就会出现。
为什么XML处理起来很麻烦
如果你习惯了JSON,XML会让你感到非常烦恼。原因如下:
冗长。 比较一下:
{"user": {"id": 1, "name": "Alice", "active": true}}
与:
<user>
<id>1</id>
<name>Alice</name>
<active>true</active>
</user>
两者传达相同的数据。XML更长,一目了然地更难阅读,手写时更容易出错。
属性与元素的歧义。 XML允许你将数据表示为属性(<user id="1">)或子元素(<id>1</id>)。两者都有效,不同的XML模式做出不同的选择。这种不一致意味着不读取模式就无法预测结构。
命名空间。 XML命名空间允许来自不同词汇表的元素名称共存而不发生冲突。对于复杂文档来说强大且必要,但当你试图提取简单值时却是个头疼的问题。
混合内容。 XML支持文本与子元素混合:
<p>这是<em>重要的</em>文本。</p>
这无法干净地映射到JSON。
这就是为什么在JavaScript或Python中处理XML需要适当的XML库而不是字符串解析。当结构允许时,转换为JSON会让数据处理容易得多。
JSON如何不同地建模数据
JSON有一个更简单、更严格的类型模型:
- 字符串 —
"hello" - 数字 —
42,3.14 - 布尔值 —
true,false - Null —
null - 数组 —
[1, 2, 3] - 对象 —
{"key": "value"}
JSON中的一切都是这六种类型之一。没有属性、命名空间、混合内容或处理指令的概念。这种简洁性是JSON赢得API设计的原因——只有一种方式表示数据。
使用XML转JSON工具
XML转JSON转换器直接在浏览器中处理转换——无需向服务器发送数据,无需安装。
基本用法:
- 将XML粘贴到左侧面板
- 点击转换(或自动转换)
- JSON输出出现在右侧
- 复制JSON并在需要的地方使用
对于这样的简单XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<name>Alice</name>
<age>30</age>
<email>alice@example.com</email>
</person>
你会得到干净的JSON:
{
"person": {
"name": "Alice",
"age": "30",
"email": "alice@example.com"
}
}
注意age在JSON输出中是字符串("30"而不是30)。XML没有数字类型——一切都是文本。
属性前缀约定
当XML元素有属性时,它们在JSON输出中带有@前缀出现:
<book id="123" lang="en">
<title>Clean Code</title>
<author>Robert Martin</author>
</book>
转换为:
{
"book": {
"@id": "123",
"@lang": "en",
"title": "Clean Code",
"author": "Robert Martin"
}
}
@前缀是广泛使用的约定(源自Badgerfish约定,用于多个流行的XML-JSON转换库)。它在JSON结构中区分属性和子元素。在代码中使用这个JSON时,通过data.book["@id"]访问属性值。
重复元素变成数组
最重要的(也可能令人惊讶的)转换行为:当同一标签在同一级别多次出现时,它变成JSON数组。
<library>
<book>
<title>Clean Code</title>
</book>
<book>
<title>The Pragmatic Programmer</title>
</book>
<book>
<title>Refactoring</title>
</book>
</library>
转换为:
{
"library": {
"book": [
{"title": "Clean Code"},
{"title": "The Pragmatic Programmer"},
{"title": "Refactoring"}
]
}
}
这是正确且有用的。但它造成了不一致:如果图书馆只有一本书,book将是一个对象而不是数组。这让很多假设JSON结构始终一致的代码出了问题。
如果你在编写代码来消费这个转换后的JSON,始终处理字段可能是对象或数组的情况。在JavaScript中,访问索引位置之前用Array.isArray(data.library.book)检查。
转换不完美的情况
一些XML特性无法干净地转换为JSON。
命名空间。 命名空间声明(xmlns="...")可能根据转换器而保留或不保留。
CDATA部分。 大多数转换器从CDATA块中提取文本内容。如果CDATA内容包含有意的标记或特殊字符,请仔细验证输出。
处理指令和XML注释。 通常会被丢弃。
混合内容。 最难处理的情况。转换器通常只保留子元素值,丢失周围的文本。
对于简单的数据交换——API、配置、数据源——这些边缘情况很少重要。对于以文档为中心的XML(内容管理、技术文档),你需要注意它们。
实际用例
消费SOAP API响应
SOAP响应转换后,你得到一个可以在JavaScript中使用的JSON结构,无需完整的SOAP库。命名空间前缀(soap:)作为键名的一部分出现。对于快速数据提取,这通常已经足够。
解析RSS订阅
RSS订阅是具有可预测结构的XML文档。转换为JSON使其在现代JavaScript中处理起来容易得多。转换后,data.rss.channel.item是一个你可以直接迭代的文章数组。
读取Android资源文件
Android的strings.xml资源文件是XML。转换为JSON使得在构建脚本或工具中处理这些文件变得容易,无需完整的Android SDK。
编程式转换
如果你需要在代码中重复将XML转换为JSON,快速浏览器工具不是答案。以下是选项:
JavaScript/Node.js: fast-xml-parser是使用最广泛的库,快速且可配置。xml2js较老但仍然流行。
const { XMLParser } = require('fast-xml-parser');
const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@' });
const result = parser.parse(xmlString);
Python: xmltodict将XML转换为Python字典(可以干净地映射到JSON)。
import xmltodict, json
result = xmltodict.parse(xml_string)
json_output = json.dumps(result, indent=2)
Go: encoding/xml在标准库中,但API需要结构体定义。github.com/clbanning/mxj提供类似xmltodict的动态转换。
对于一次性转换或调试,XML转JSON工具比写这些代码更快。对于生产管道,选择适合你语言的库并一次性配置好。
XML不会消失——基于XML的系统的安装基础是巨大的,企业不会按计划重写运行良好的基础设施。实用技能是当XML出现时知道如何高效地使用它,而不是每次都与之较劲。
处理结构化数据的相关工具: