
PHP 里用 json_decode() 解析 JSON 后怎么转成 XML
不能直接转,PHP 没内置函数做这事。得自己构造 XML 结构,或者借助第三方逻辑。核心难点是 JSON 的嵌套、同级数组、空值、数字键这些,在 XML 里没天然对应——比如 ["a","b"] 是该转成多个同名节点,还是带 index 属性的单节点?null 是留空、删掉,还是写成 <item xsi:nil="true"></item>?这些都得你定规则。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 别手写完整 DOM 构建,太容易漏闭合标签或转义错误;用
SimpleXML+DOMDocument组合更稳 - 遇到关联数组(
["name"=>"Tom", "age"=>25]),直接映射为 XML 元素属性或子节点,取决于你的数据契约 - 纯索引数组(
[1,2,3])必须包装一层父节点,否则 XML 会非法(根节点只能有一个) - 字符串里含
&、、<code>>必须用htmlspecialchars($val, ENT_XML1)转义,否则生成的 XML 会解析失败
PHP 中用 simplexml_load_string() 读 XML 后怎么安全转成 JSON
直接 json_encode() 会出问题:SimpleXML 对象不是普通数组,里面混着对象、CDATA、命名空间信息,JSON 序列化后字段名可能消失、类型错乱(比如数字变成字符串)、甚至返回空对象。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 先用
json_decode(json_encode((array)$xml), true)强制转成关联数组,这是最简兜底方案 - 如果 XML 有命名空间,
simplexml_load_string()默认忽略,得加参数SIMPLEXML_LOAD_DEFAULT_ENTITIES并手动处理children()和attributes() - 注意空元素:
<price></price>在 SimpleXML 里是对象但内容为空,转 JSON 后可能变成"price":{},需提前判断并设为null或空字符串 - 日期、布尔等语义类型在 XML 里全是字符串,JSON 不会自动还原,得靠业务层二次识别和转换
为什么用 json_encode() + json_decode() 做中间桥接会丢数据
因为 JSON 和 XML 数据模型根本不同:JSON 没属性、没注释、没处理指令、不区分元素和文本节点,而 XML 有。一旦你把 XML 转成数组再 JSON 化,再反向转回数组去建 XML,原始结构就断了。
常见错误现象:
- XML 属性(如
<user id="123"></user>)在json_encode()后消失,除非你提前把属性提取到子键里(如["@id" => "123"]) - 同名多节点(
<tag>a</tag><tag>b</tag>)被 PHP 自动合并成单个字符串或覆盖,除非你强制用索引数组包装 - CDATA 内容被当普通文本转义,导致 JS 里解析时多出
<这类实体 - XML 声明(
<?xml version="1.0"?>)和 DOCTYPE 完全丢失,后续系统校验会失败
生产环境推荐的轻量互转方案
不用重写轮子,也不用引入整个 spatie/array-to-xml 或 php-xmlrpc。两段够用的函数就能 cover 80% 场景,关键是控制边界。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- JSON → XML:用封装好的递归函数,对数组键名做
preg_replace('/[^a-z0-9_\-]/i', '', $key)过滤,避免非法标签名;数值键统一转成item+index属性 - XML → JSON:优先用
simplexml_load_file()或simplexml_load_string(),然后调用json_encode($xml, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),再json_decode(..., true),比手动遍历快且少 bug - 所有转换前后加
libxml_use_internal_errors(true)+libxml_get_errors()捕获 XML 解析错误,别让格式问题静默失败 - 如果接口要双向兼容,建议协议层就约定用 JSON,XML 只作为遗留系统适配层,避免反复转换
真正麻烦的从来不是语法转换,而是两边对“空”“重复”“顺序”“类型”的隐含理解不一致。每次改一个字段,最好连带检查 XML Schema 和 JSON Schema 是否还对得上。











