PHP中JSON转XML时为数组添加容器元素及item子节点的实现方法
JSON转XML自定义数组包裹格式实现方案
原问题描述
在开始之前,我已查阅过本站及互联网上的大量相关帖子和主题,但目前找到的所有解决方案都无法处理我遇到的这个JSON转换需求。
我需要将一个JSON文件转换为XML文件,常规转换方式存在不符合我需求的问题。比如下面这段JSON:
{ "data": { "key4":{ "sample8": [ { "sample9":"val", "sample10":"val" }, { "sample11":"val", "sample12":"val" }, { "sample13":"val", "sample14":"val" } ] } } }用常规方式转换后得到的XML是这样的:
<?xml version="1.0"?> <data> <key4> <sample8> <sample9>val</sample9> <sample10>val</sample10> </sample8> <sample8> <sample11>val</sample11> <sample12>val</sample12> </sample8> <sample8> <sample13>val</sample13> <sample14>val</sample14> </sample8> </key4> </data>我需要的效果是:每个JSON数组在XML中保留外层容器元素,数组内的每一项都用指定元素名(比如
item)包裹,最终要得到的XML如下:<?xml version="1.0"?> <data> <key4> <sample8> <item> <sample9>val</sample9> <sample10>val</sample10> </item> <item> <sample11>val</sample11> <sample12>val</sample12> </item> <item> <sample13>val</sample13> <sample14>val</sample14> </item> </sample8> </key4> </data>我试过多种方法都没达到预期,求指导。如果PHP实现不了,用其他编程语言也可以。
解决方法
常规的JSON转XML工具默认会将数组元素直接展开为父标签的重复节点,要实现自定义数组项包裹,只需手动写递归逻辑处理即可,以下提供两种常用语言的无第三方依赖实现方案:
PHP实现
使用内置SimpleXMLElement类实现,逻辑为递归遍历JSON解码后的结构,遇到索引数组时先创建外层容器,再为每个子项创建item节点:
<?php // 自定义JSON转XML函数 function jsonToXml($data, $xmlNode) { foreach ($data as $key => $value) { // 处理JSON数组(PHP中对应索引数组) if (is_array($value) && array_keys($value) === range(0, count($value) - 1)) { $container = $xmlNode->addChild($key); foreach ($value as $item) { $itemNode = $container->addChild('item'); jsonToXml($item, $itemNode); } } // 处理关联数组/对象 else if (is_array($value) || is_object($value)) { $subNode = $xmlNode->addChild($key); jsonToXml($value, $subNode); } // 处理字符串、数字等基础值 else { $xmlNode->addChild($key, htmlspecialchars($value)); } } } // 使用示例 $jsonStr = '替换为你的JSON字符串'; $data = json_decode($jsonStr, true); // 初始化根节点,可根据需求修改根节点名 $xml = new SimpleXMLElement('<?xml version="1.0"?><root></root>'); jsonToXml($data, $xml); // 格式化输出XML $dom = new DOMDocument('1.0'); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->loadXML($xml->asXML()); echo $dom->saveXML(); ?>
如果需要修改数组项的标签名,直接替换代码中的'item'为你需要的名称即可。
Python实现
使用内置xml.etree.ElementTree模块实现,逻辑和PHP版本一致:
import json import xml.etree.ElementTree as ET from xml.dom import minidom def json_to_xml(data, parent_node): if isinstance(data, dict): for key, value in data.items(): if isinstance(value, list): # 处理数组,先创建外层容器节点 container = ET.SubElement(parent_node, key) for item in value: item_node = ET.SubElement(container, 'item') json_to_xml(item, item_node) elif isinstance(value, dict): sub_node = ET.SubElement(parent_node, key) json_to_xml(value, sub_node) else: sub_node = ET.SubElement(parent_node, key) sub_node.text = str(value) # 使用示例 json_str = '替换为你的JSON字符串' data = json.loads(json_str) # 初始化根节点,可根据需求修改根节点名 root = ET.Element('root') json_to_xml(data, root) # 格式化输出 rough_string = ET.tostring(root, 'utf-8') reparsed = minidom.parseString(rough_string) pretty_xml = reparsed.toprettyxml(indent=" ") print(pretty_xml)
内容的提问来源于stack exchange,提问作者Sonal
相关产品推荐
相关产品推荐

