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

使用SimpleXML将XML解析为数组:设备XML结构处理咨询

用SimpleXML将设备XML解析为数组的解决方案

嘿,我来帮你搞定这个需求!针对你从设备拿到的XML结构,用PHP的SimpleXML转成数组其实很顺手,下面给你两种实用的方法,你可以根据需求选:


第一步:确保XML结构完整

先提个小前提:你给出的XML里<ptu...部分没写完,解析前一定要确保XML是闭合且格式正确的,不然SimpleXML会报错。比如补全后的示例XML大概是这样:

<packet>
  <info action="fiscalmemory" fiscalmemorysize="1048576" recordsize="464" fiscal="1" uniqueno="ABC12345678" nip="123-456-78-90" maxrecordscount="2144" recordscount="7" maxreportscount="1830" reportscount="4" resetmaxcount="200" resetcount="0" taxratesprglimit="30" taxratesprg="1" currencychangeprglimit="4" currencychangeprg="0" fiscalstartdate="dd-mm-yyyy hh:dd:ss" fiscalstopdate="dd-mm-yyyy hh:dd:ss" currencyname="PLN" />
  <ptu id="1" value="sample">Some content</ptu>
</packet>

方法一:快速转换(适合简单结构)

用json_encode+json_decode的组合可以快速把SimpleXMLElement对象转成数组,虽然属性会被放到@attributes子数组里,但胜在代码简洁:

// 假设$xmlString是从设备获取到的XML字符串
$xml = simplexml_load_string($xmlString);
// 转成数组
$xmlArray = json_decode(json_encode($xml), true);

// 打印看看结果
print_r($xmlArray);

输出的数组大概是这样的(只展示关键部分):

Array
(
    [info] => Array
        (
            [@attributes] => Array
                (
                    [action] => fiscalmemory
                    [fiscalmemorysize] => 1048576
                    [recordsize] => 464
                    // 其他属性...
                )

        )
    [ptu] => Array
        (
            [@attributes] => Array
                (
                    [id] => 1
                    [value] => sample
                )
            [0] => Some content
        )
)

方法二:自定义递归转换(更灵活,属性直接平铺)

如果你希望把标签的属性直接和子内容放在同一层级,不用@attributes嵌套,可以写一个递归函数来处理:

function xmlToArray($xml) {
    $result = [];

    // 处理标签属性
    foreach ($xml->attributes() as $key => $value) {
        $result[$key] = (string)$value;
    }

    // 处理子节点
    foreach ($xml->children() as $child) {
        $childArray = xmlToArray($child);
        // 如果子节点有多个同名的,转成数组
        if (isset($result[$child->getName()])) {
            if (!is_array($result[$child->getName()])) {
                $result[$child->getName()] = [$result[$child->getName()]];
            }
            $result[$child->getName()][] = $childArray;
        } else {
            $result[$child->getName()] = $childArray;
        }
    }

    // 如果节点有文本内容,添加到数组里
    if (trim((string)$xml) !== '') {
        // 如果已经有属性或子节点,用'_content'存文本,否则直接存文本
        if (!empty($result)) {
            $result['_content'] = trim((string)$xml);
        } else {
            $result = trim((string)$xml);
        }
    }

    return $result;
}

// 使用示例
$xml = simplexml_load_string($xmlString);
$xmlArray = xmlToArray($xml);

print_r($xmlArray);

这种方法的输出会更直观,比如<info>的属性直接在$xmlArray['info']下,不需要再取@attributes:

Array
(
    [info] => Array
        (
            [action] => fiscalmemory
            [fiscalmemorysize] => 1048576
            [recordsize] => 464
            // 其他属性直接平铺...
        )
    [ptu] => Array
        (
            [id] => 1
            [value] => sample
            [_content] => Some content
        )
)

注意事项

  • 一定要确保XML格式正确,有闭合标签,没有语法错误,否则simplexml_load_string会返回false,你可以加个错误检查:
    $xml = simplexml_load_string($xmlString);
    if (!$xml) {
        die('XML解析失败,请检查XML格式');
    }
    
  • 如果XML里有多个同名的子节点(比如多个<ptu>),自定义函数会自动把它们转成数组的元素,避免覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:02:48