You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中带属性的嵌套XML转换为多维数组的递归处理问题

PHP中带属性的嵌套XML转换为多维数组的递归处理问题

看起来你已经迈出了不错的第一步,但确实遇到了递归处理嵌套节点的问题——你的当前函数只处理了顶层的XML元素,没有深入解析子节点(比如第二个item里的subb元素),而且重复节点的处理逻辑也有点小问题。我来帮你调整一下函数,让它能递归处理所有层级,同时正确处理重复节点的数组结构。

首先明确核心需求:

  • 把XML的属性转为数组元素(比如统一用@attributes键存储)
  • 节点的文本值存为@value
  • 嵌套的子节点也要按同样规则递归转换
  • 同名的重复节点自动转为数组形式,单个节点则保持为键值对

那我们来修改xmlToArray函数,完善递归逻辑和重复节点处理:

$xmlString = '<root><item id="1" name="ItemOne">Item Value 1</item><item id="2" name="ItemTwo"><subb>Sub Value 1</subb><subb>Sub Value 2</subb></item><item id="3" name="ItemThree">Value 3</item><something>something value</something></root>';

function xmlToArray($xmlNode) {
    $array = [];
    
    // 处理当前节点的属性
    $attributes = (array)$xmlNode->attributes();
    if (!empty($attributes)) {
        $array['@attributes'] = array_map('trim', (array)$attributes['@attributes']);
    }
    
    // 处理当前节点的文本值
    $textValue = trim((string)$xmlNode);
    if (!empty($textValue)) {
        $array['@value'] = $textValue;
    }
    
    // 递归处理所有子节点
    foreach ($xmlNode->children() as $childNode) {
        $childArray = xmlToArray($childNode);
        $childKey = (string)$childNode->getName();
        
        // 处理重复节点:如果键已存在,自动转为数组格式
        if (isset($array[$childKey])) {
            // 若当前值不是数组,先把已有值包装成数组
            if (!is_array($array[$childKey]) || !isset($array[$childKey][0])) {
                $array[$childKey] = [$array[$childKey]];
            }
            $array[$childKey][] = $childArray;
        } else {
            $array[$childKey] = $childArray;
        }
    }
    
    // 优化:如果节点只有文本值,直接返回文本(可选,根据需求调整)
    if (empty($array['@attributes']) && count($array) === 1 && isset($array['@value'])) {
        return $array['@value'];
    }
    
    return $array;
}

// 加载XML并执行转换
$xmlObject = simplexml_load_string($xmlString);
$resultArray = xmlToArray($xmlObject);

// 打印结果查看结构
echo '<pre>'.print_r($resultArray, true).'</pre>';

代码关键说明:

  1. 递归解析:函数会调用自身处理每个子节点,不管XML嵌套多少层,都能逐层解析成对应结构的数组。
  2. 属性与文本分离:用@attributes统一存储节点属性,@value存储文本值,结构更清晰规范。
  3. 重复节点处理:遇到同名节点时,自动将已有值转为数组并追加新节点数据,避免覆盖问题。
  4. 轻量优化:对于只有文本值的节点,直接返回文本而非嵌套数组,让结果更简洁(不需要的话可以删掉这个判断)。

运行后你会得到符合预期的多维数组,其中第二个item里的两个subb节点会被正确转为数组:

Array
(
    [item] => Array
        (
            [0] => Array
                (
                    [@attributes] => Array
                        (
                            [id] => 1
                            [name] => ItemOne
                        )

                    [@value] => Item Value 1
                )

            [1] => Array
                (
                    [@attributes] => Array
                        (
                            [id] => 2
                            [name] => ItemTwo
                        )

                    [subb] => Array
                        (
                            [0] => Sub Value 1
                            [1] => Sub Value 2
                        )
                )

            [2] => Array
                (
                    [@attributes] => Array
                        (
                            [id] => 3
                            [name] => ItemThree
                        )

                    [@value] => Value 3
                )

        )

    [something] => something value
)

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 08:58:07