XML到JSON:比看起来更难
XML和JSON之间的转换常常产生令人意外的结果。了解属性映射、数组处理和命名空间等转换难点,学习如何正确处理边缘情况避免数据丢失。
你有XML数据。你的JavaScript应用需要JSON。转换它然后继续,对吗?
除了转换产生意外结果。应该存在的数组不存在。属性最终在奇怪的地方。单个项目随机变成数组。
XML和JSON以不同方式建模数据。在它们之间转换需要决策。
根本不匹配
JSON有:对象、数组、字符串、数字、布尔值、null。
XML有:元素、属性、文本内容、命名空间、注释、CDATA。
没有1:1映射。
数组问题
XML没有数组。它有重复的元素。
<users>
<user>Alice</user>
<user>Bob</user>
</users>
这应该可能变成:
{"users": {"user": ["Alice", "Bob"]}}
但这个怎么办:
<users>
<user>Alice</user>
</users>
一个元素。它是有一个项目的数组,还是只是字符串?不同的转换器决定不同。
一致性很重要。如果user有时是数组有时是字符串,你的代码会崩溃。
属性问题
XML有属性。JSON没有。
<product id="123">Widget</product>
常见转换策略:
{"product": {"_id": "123", "_text": "Widget"}}
{"product": {"@id": "123", "#text": "Widget"}}
{"product": {"$": {"id": "123"}, "_": "Widget"}}
每个约定都不同。知道你的转换器产生什么。
命名空间问题
XML命名空间创建像soap:Envelope这样的限定名。JSON没有命名空间概念。
转换器要么:
- 在属性名中包含前缀:
"soap:Envelope" - 去除前缀:
"Envelope" - 为命名空间处理创建嵌套结构
每种方法都有权衡。
实用技巧
保持一致。 选择一个转换库并坚持使用它。混合转换器产生不一致的结构。
强制数组。 如果元素可以有多个实例,配置转换器总是产生数组,即使对于单个元素。
测试边缘情况。 转换真实数据,而不只是样本。生产数据中的边缘情况会让你惊讶。
考虑替代方案。 如果你控制两端,考虑从一开始就使用JSON。来回转换会丢失信息。
JSON到XML挑战
反向也有问题。
没有数组表示。 JSON数组变成重复元素。你需要命名这些元素。
{"items": [1, 2, 3]}
变成什么?<items><item>1</item>...</items>?"item"从哪来?
数字类型。 JSON区分数字和字符串。XML不区分。123可能变成<value>123</value>——那是数字还是字符串?
何时转换
与遗留系统集成。 SOAP API和旧企业系统使用XML。在边界转换。
处理XML数据。 JavaScript处理JSON比XML好得多。转换、处理、需要时转换回来。
一次性迁移。 从基于XML的系统迁移到基于JSON的系统。
何时不转换
往返要求。 XML → JSON → XML通常丢失信息。属性、命名空间、排序。
模式验证。 XML有强大的模式语言(XSD)。JSON Schema不那么成熟。
文档处理。 XML的混合内容模型(带嵌入元素的文本)不能干净地映射到JSON。
XML和JSON以不同方式表示数据。转换需要关于数组、属性和命名空间的选择。理解你的转换器的行为并用现实数据测试。