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

PHP如何完整转换含属性的XML为数组?

PHP如何将XML完整转换为包含所有属性的数组

用simplexml_load_string转XML再通过json_encode/json_decode转数组的方式确实会丢失节点属性——因为SimpleXMLElement转JSON时默认不会单独提取属性信息。PHP完全支持把XML完整转换为包含所有属性的数组,给你两个实用的实现方案:

方法一:递归遍历SimpleXMLElement构建数组

SimpleXMLElement提供了attributes()方法可以获取节点属性,我们可以写一个递归函数遍历所有节点,把属性、子节点和文本内容整合到数组中:

function xmlToArray(\SimpleXMLElement $xml): array
{
    $result = [];

    // 提取节点属性
    foreach ($xml->attributes() as $attrName => $attrValue) {
        $result['@attributes'][(string)$attrName] = (string)$attrValue;
    }

    // 处理子节点
    foreach ($xml->children() as $childName => $childNode) {
        $childData = xmlToArray($childNode);
        // 若同一节点名重复出现,自动转为数组格式
        if (isset($result[$childName])) {
            if (!is_array($result[$childName]) || !isset($result[$childName][0])) {
                $result[$childName] = [$result[$childName]];
            }
            $result[$childName][] = $childData;
        } else {
            $result[$childName] = $childData;
        }
    }

    // 提取节点文本内容
    $textContent = trim((string)$xml);
    if (!empty($textContent)) {
        if (empty($result)) {
            $result = $textContent;
        } else {
            $result['@value'] = $textContent;
        }
    }

    return $result;
}

// 使用示例
$xmlStr = '<root><param name="id">123</param><param name="name">test</param></root>';
$xml = simplexml_load_string($xmlStr);
$array = xmlToArray($xml);
print_r($array);

这个函数会把属性存储在@attributes键下,节点文本存储在@value键下,重复节点会自动转为数组结构。

方法二:用DOMDocument递归处理

如果需要更精细的控制(比如区分文本节点、CDATA块等),可以用DOMDocument来实现:

function domNodeToArray(\DOMNode $node): mixed
{
    $result = [];

    // 处理元素节点的属性
    if ($node instanceof \DOMElement) {
        foreach ($node->attributes as $attrName => $attrNode) {
            $result['@attributes'][$attrName] = $attrNode->value;
        }
    }

    // 遍历子节点
    foreach ($node->childNodes as $child) {
        if ($child instanceof \DOMText) {
            $text = trim($child->nodeValue);
            if (!empty($text)) {
                if (empty($result)) {
                    $result = $text;
                } else {
                    $result['@value'] = $text;
                }
            }
        } elseif ($child instanceof \DOMElement) {
            $childData = domNodeToArray($child);
            $childName = $child->tagName;
            // 处理重复节点
            if (isset($result[$childName])) {
                if (!is_array($result[$childName]) || !isset($result[$childName][0])) {
                    $result[$childName] = [$result[$childName]];
                }
                $result[$childName][] = $childData;
            } else {
                $result[$childName] = $childData;
            }
        }
        // 如需支持CDATA,可添加判断:elseif ($child instanceof \DOMCDATASection)
    }

    return $result;
}

// 使用示例
$xmlStr = '<root><param name="id">123</param><param name="name">test</param></root>';
$dom = new \DOMDocument();
$dom->loadXML($xmlStr);
$array = domNodeToArray($dom->documentElement);
print_r($array);

这个方案能处理更多XML节点类型,适合结构复杂的XML场景。

内容的提问来源于stack exchange,提问作者user3022527

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:10:02