XML转JSON易因属性/文本/子元素结构不统一出错,推荐xml2js或xmltodict并启用explicitArray;JSON转XML须补根节点、显式标注类型;校验需归一化后diff,生产环境禁用在线工具。

XML 转 JSON 时,属性和文本内容容易混在一起
XML 的 id 属性、text() 内容、子元素在转成 JSON 后结构不统一,是出错最频繁的地方。比如 <user id="123">Alice</user>,不同库可能转成 {"user": {"@id": "123", "#text": "Alice"}} 或 {"user": {"id": "123", "value": "Alice"}} —— 没有标准,全看库怎么设计。
实操建议:
- 优先用
xml2js(Node.js)或xmltodict(Python),它们约定较清晰:@开头表示属性,#text表示纯文本节点 - 如果 XML 有同名多子节点(如多个
<item>),默认会转成数组;但单个时只生成对象——加explicitArray: true(xml2js)可强制统一为数组,避免后续逻辑判空出错 - 别依赖在线工具的“美化”结果做生产解析——它们多数用浏览器 DOM 解析 XML,对命名空间、CDATA、DOCTYPE 支持极弱,校验不了真实兼容性
JSON 转回 XML 时,根节点缺失或类型丢失
JSON 是无根、无类型的扁平结构,而 XML 必须有且仅有一个根元素,且数字、布尔值在 XML 中全是字符串。直接把 {"name": "Tom", "age": 25} 转 XML,很可能得到 <name>Tom</name><age>25</age> —— 缺根、无类型、无法反向解析回原 JSON。
实操建议:
- 手动补根:转前确保 JSON 是单对象,键名即根名,例如
{"user": {"name": "Tom", "age": 25}}→<user><name>Tom</name><age>25</age></user> - 数值/布尔不要靠 XML 标签名暗示类型;如需保留,得加属性,比如
{"age": {"#text": "25", "@type": "number"}},再配合自定义序列化逻辑 - 在线工具若不让你指定根名或忽略
@type字段,那它转出的 XML 基本无法无损还原,别用于接口联调
校验互转是否等价,不能只比对字符串
XML 和 JSON 对空白、属性顺序、编码方式敏感,但语义上可能完全一致。比如 <a x="1" y="2"> 和 <a y="2" x="1"> 是等价 XML,但字符串比较直接报错;JSON 中 "1" 和 1 类型不同,但某些 XML→JSON 库会全转成字符串。
实操建议:
- 校验前先归一化:XML 用
libxmljs或lxml解析后再序列化(自动排序属性、标准化缩进);JSON 用JSON.stringify(obj, null, 0)去格式、再解析一次消除浮点精度误差 - 重点核对三处:① 所有属性是否都落在
@下;② 文本内容是否没被误当子元素;③ 数组长度是否一致(特别注意单元素变对象 vs 多元素变数组) - 写个最小验证脚本比在线工具靠谱:读入 XML → 转 JSON → 再转回 XML → 归一化后 diff,比肉眼贴代码快得多
线上服务慎用通用在线转换工具
多数标榜“XML/JSON 互转”的网站,底层用的是浏览器 DOMParser + XMLSerializer,根本处理不了 xmlns、<![CDATA[...]]>、处理指令(<?xml ...?>)、注释,甚至会静默丢弃非法字符。你粘进去的 XML 看似转成功了,实际关键信息已损坏。
实操建议:
- 涉及生产数据,必须本地跑真实依赖:Node.js 用
xml2js+builder;Python 用xmltodict+dicttoxml(注意后者不维护了,推荐xmljson库) - 如果必须用在线工具临时调试,先用
xmllint --noout file.xml确认 XML 语法合法,再剔除所有命名空间和 CDATA 再粘贴 - 任何含敏感字段(如
password、token)的 XML,绝不能发到第三方网站——没有 HTTPS 传输、无隐私政策、缓存不可控










