使用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
相关产品推荐
相关产品推荐

