JSON vs XML: Which Data Format Should You Use?
XML dominated data interchange for over a decade. Then JSON showed up and changed everything. Here's why — and when XML is still the better choice.
快速历史课
XML(可扩展标记语言)诞生于1998年,那时Java小程序和SOAP网络服务是尖端技术。它被设计为SGML的简化子集——SGML是HTML背后的元语言——并且它做得很好。多年来,XML是数据交换、配置、文档存储以及几乎所有其他用途的标准。
然后,在2000年代初,网络开发人员开始构建AJAX应用程序,并意识到他们需要比XML更轻量的东西来在浏览器和服务器之间传递数据。道格拉斯·克罗克福德在2001-2002年间正式化了JSON,转变迅速。到2010年,大多数新的REST API都在使用JSON。到2015年,这甚至不再是一个争论。
但这里有一个人们常常搞错的事情:XML并没有“失败”。它退回到它真正擅长的领域。理解这些领域是将深思熟虑的架构决策与盲目跟风区分开的关键。
语法比较
让我们看看相同的数据——一本书的列表——在这两种格式中的表示:
JSON
{
"library": {
"books": [
{
"isbn": "978-0-13-468599-1",
"title": "程序员的修炼之道",
"author": "大卫·托马斯, 安德鲁·亨特",
"year": 2019,
"available": true,
"tags": ["编程", "最佳实践", "职业"]
},
{
"isbn": "978-0-596-51774-8",
"title": "JavaScript: The Good Parts",
"author": "道格拉斯·克罗克福德",
"year": 2008,
"available": false,
"tags": ["javascript", "编程"]
}
]
}
}
XML
<?xml version="1.0" encoding="UTF-8"?>
<library>
<books>
<book isbn="978-0-13-468599-1" available="true">
<title>程序员的修炼之道</title>
<author>大卫·托马斯, 安德鲁·亨特</author>
<year>2019</year>
<tags>
<tag>编程</tag>
<tag>最佳实践</tag>
<tag>职业</tag>
</tags>
</book>
<book isbn="978-0-596-51774-8" available="false">
<title>JavaScript: The Good Parts</title>
<author>道格拉斯·克罗克福德</author>
<year>2008</year>
<tags>
<tag>javascript</tag>
<tag>编程</tag>
</tags>
</book>
</books>
</library>
XML版本大约大40%,这是典型的。每个元素名称出现两次(开闭标签),数组需要包装元素。XML还有“属性”与“元素”的概念——注意isbn和available是<book>标签上的属性,而其他字段是子元素。这种灵活性既是一个特性,也是无尽设计争论的来源。
相比之下,JSON只有一种方式来处理事情:键和值。没有属性与元素的区别。没有闭合标签。更少的仪式,更少的模糊。
自己试试: 将JSON粘贴到我们的JSON转XML转换器中,立即查看XML等效项。或者通过XML转JSON进行反向转换。
特性比较
| 特性 | JSON | XML |
|---|---|---|
| 冗长性 | 紧凑 | 冗长(开闭标签) |
| 可读性 | 适合数据结构 | 适合文档 |
| 注释 | ❌ 不支持 | ✅ 支持 (<!-- comment -->) |
| 模式验证 | JSON Schema(单独规范) | XSD, DTD, RELAX NG(成熟且强大) |
| 命名空间支持 | ❌ 不支持 | ✅ 支持(避免命名冲突) |
| 数据类型 | 字符串、数字、布尔值、null、对象、数组 | 一切都是文本(仅通过模式确定类型) |
| 属性 | ❌ 不支持(仅键) | ✅ 支持(元素上的元数据) |
| 混合内容 | ❌ 不支持 | ✅ 支持(文本与标记交错) |
| 转换 | 手动代码 | XSLT(声明式转换) |
| 查询语言 | JSONPath, JMESPath | XPath, XQuery(更成熟) |
| 解析速度 | 快(简单语法) | 慢(复杂语法,验证) |
| 浏览器原生解析 | ✅ JSON.parse() | ✅ DOMParser |
| 文件大小(相同数据) | 较小(约60-70%的XML) | 较大(冗余标签) |
| 工具生态系统 | 现代,增长中 | 成熟,广泛 |
XML仍然胜出的场合
我知道完全抛弃XML是很诱人的。抵制这种冲动。有一些特定领域,XML不仅足够,而且真正优越。
1. 文档标记和混合内容
这是XML的杀手级特性。考虑一个带有内联格式的段落:
<paragraph>
这是<bold>重要</bold>的文本,其中嵌入了一个<link href="/page">超链接</link>。
</paragraph>
尝试用JSON表示这个。你会得到一些可怕的东西——一个混合字符串和对象元素的数组,或者某种标记转义语法。JSON是为结构化数据设计的,而不是文档。XML则是为两者设计的。
这就是为什么HTML(XML的一个表亲)、DocBook、DITA和出版格式都使用基于XML的语法。EPUB文件是XML格式的。Microsoft Office文件(.docx, .xlsx)是压缩的XML。文档世界依赖于XML,而JSON不会取代这个王座。
2. SOAP网络服务
企业系统,尤其是在银行、医疗和政府领域,仍然严重依赖SOAP。这些服务使用带有严格模式(WSDL)的XML,并且它们不会很快迁移到REST。如果你正在与遗留企业API集成,无论你喜欢与否,你都将使用XML。
3. XSLT转换
XSLT允许你声明性地转换XML文档——重构、过滤、格式化——而无需编写过程代码。它在从XML数据生成HTML报告、在XML模式之间转换和文档管道处理方面非常强大。JSON没有接近XSLT能力的等效物。
4. 命名空间
当你需要在单个文档中合并来自多个源的数据而不发生命名冲突时,XML命名空间优雅地解决了这个问题:
<root xmlns:hr="http://example.com/hr"
xmlns:fin="http://example.com/finance">
<hr:employee>
<hr:name>爱丽丝</hr:name>
<fin:salary currency="USD">95000</fin:salary>
</hr:employee>
</root>
JSON没有命名空间的概念。如果两个API使用相同的键名但含义不同,你就得自己解决冲突。
5. RSS、Atom和SVG
RSS和Atom馈送是XML格式的。SVG图形是XML格式的。这些格式深深嵌入网络生态系统,并且不会改变。如果你正在生成或消费这些,你需要XML支持。
JSON胜出的场合
对于大多数现代开发任务,JSON是务实的选择。以下是它明显占优势的地方:
1. REST API
数字说明了一切。根据各种API调查,超过90%的公共API使用JSON作为其主要响应格式。它在传输上更轻,解析速度更快,并且直接映射到JavaScript、Python、Ruby、Go和大多数其他语言的原生数据结构。
// 调用REST API — 响应已经是JSON格式
const response = await fetch("https://api.github.com/users/octocat");
const user = await response.json();
console.log(user.login); // "octocat"
使用XML,你需要实例化一个DOM解析器,遍历节点,并手动提取文本内容。使用JSON,你只需调用.json()即可获得一个原生对象。开发者体验的差距是巨大的。
2. NoSQL数据库
MongoDB、CouchDB、DynamoDB、Firestore、Elasticsearch——整个NoSQL生态系统都是围绕JSON(或类似JSON)文档构建的。如果你的数据已经是JSON格式,将其存储在文档数据库中几乎没有摩擦。
3. 移动和前端应用
移动应用需要在带宽和电池使用上高效。JSON更小的负载大小和更快的解析速度直接转化为更好的应用性能。iOS(Codable)和Android(Gson、Moshi、Kotlin Serialization)都有出色的JSON库。
4. 配置(有一些注意事项)
package.json、tsconfig.json、.eslintrc.json——JSON在JavaScript工具生态系统中无处不在。缺乏注释在这里是一个真正的痛点,这就是为什么许多工具现在接受JSONC或JSON5。对于更复杂的配置,我建议查看YAML作为替代方案。
5. 实时通信
WebSocket消息、服务器推送事件和实时数据馈送几乎普遍使用JSON。该格式的紧凑性和原生浏览器解析使其成为高频数据交换的理想选择。
同时处理这两种格式? 我们的JSON转XML和XML转JSON转换器使得在它们之间转换变得简单。尝试粘贴你的数据,立即查看输出。
行业转变的数据
从XML到JSON的转变是戏剧性的,并且有充分的文档记录:
- Stack Overflow趋势: 被标记为“json”的问题在2013年超过“xml”,现在大约是2:1。
- 公共API格式: ProgrammableWeb的数据表明,JSON在2011年左右超过XML成为最常提供的API格式。如今,JSON以很大优势占据主导地位。
- npm生态系统: 顶级JSON解析库(内置的
JSON.parse)没有依赖关系,并且与每个JavaScript运行时一起提供。XML解析在大多数语言中需要第三方库。 - 新规范: 大多数新的数据标准(JSON-LD、GeoJSON、JSON Schema、JWT)都是基于JSON的。基于XML的规范大多处于维护模式。
尽管如此,医疗(HL7、FHIR部分使用XML)、出版(EPUB、DITA)、政府(许多遗留系统)和金融(FIX协议、ISO 20022)等行业仍然严重依赖XML。如果你在这些领域工作,精通XML并不是可选的。
性能比较
对于典型的数据负载,这两种格式的比较如下:
| 指标 | JSON | XML |
|---|---|---|
| 解析时间(1MB,Node.js) | ~15ms | ~60ms(SAX) / ~150ms(DOM) |
| 序列化时间 | ~10ms | ~45ms |
| 负载大小(格式化) | 1.0 MB | 1.5–1.7 MB |
| 负载大小(压缩) | 0.6 MB | 1.2 MB(标签无法消除) |
| Gzipped大小 | ~120 KB | ~140 KB(压缩时差距缩小) |
Gzipped比较很有趣——XML的重复标签实际上压缩得很好,因此在压缩后大小差异显著缩小。如果你提供gzipped响应(你应该这样做),负载大小的论点就没有最初看起来那么有说服力了。不过,解析速度的差异仍然显著。
迁移提示
如果你正在从XML迁移到JSON(一个常见的任务),这里有一些需要注意的事项:
- 属性没有直接的等价物。 XML属性通常变成常规JSON属性,有时转换工具会在前面加上
@。 - 混合内容难以表示。 如果你的XML中有文本与元素交错,你需要决定一个约定(比如混合字符串和对象的数组)。
- 命名空间信息会丢失。 JSON没有命名空间的概念,因此你需要手动处理冲突。
- 顺序可能重要也可能不重要。 XML元素的顺序是重要的。JSON对象键的顺序在技术上没有保证(尽管大多数实现保留插入顺序)。
- 转换后进行验证。 使用我们的JSON验证器确保转换后的输出有效,并使用JSON比较工具验证数据完整性。
结论
对于大多数现代Web开发,JSON是正确的默认选择。它更简单、更轻、更快解析,并且在浏览器中原生支持。生态系统的动量是压倒性的。
但“对所有事情都使用JSON”是个坏建议。XML在以文档为中心的数据、混合内容、复杂模式验证、命名空间密集的集成和遗留企业系统中仍然是更好的选择。了解这两种格式——以及每种格式适用的时机——使你成为一个全面的开发者。
根据我的经验,最佳方法是务实:使用你所工作的生态系统所期望的格式,不要逆流而行。在需要时在它们之间转换,然后继续解决实际问题。
继续探索:
- 什么是JSON? — 完整的初学者指南
- JSON与YAML — 另一种常见格式比较
- JSON转XML转换器
- XML转JSON转换器
- JSON格式化工具 — 立即格式化和验证JSON