如何使用PHP遍历嵌套重复节点XML 提取id/name并按id降序排序
问题说明
需要通过PHP处理API返回的XML响应,提取所有层级folder节点的id和name字段组成数组,按id降序排序后输出对应name内容。
待处理的XML结构如下(存在多层parent嵌套的folder节点):
<?xml version="1.0"?> <success> <document> <folder> <id>295</id> <name>My Folder</name> <parent> <folder> <id>83</id> <name>Contents</name> <parent> <folder> <id>45</id> <name>Sub Folder</name> <parent> <folder> <id>21</id> <name>Root Folder</name> </folder> </parent> </folder> </parent> </folder> </parent> </folder> </document> </success>
原有基于SimpleXML的代码存在两个核心问题:一是XML加载函数用错,读取本地文件不能用simplexml_load_string直接传文件路径;二是仅遍历了最外层的folder节点,没有处理嵌套在parent下的多层folder结构,无法拿全所有节点。
原有问题代码片段:
<?php if (file_exists('api_results.xml')) { // 错误:simplexml_load_string用于加载XML格式字符串,读本地文件需要用simplexml_load_file $xml = simplexml_load_string('api_results.xml'); foreach($xml->document->folder as $folder) { $folders = array(); foreach($folder as $key => $value) { $folder[(string)$key] = (string)$value; } $folders[] = $folder; } print_r($folders); } else { exit('Failed to open api_results.xml.'); }
实现方案
核心逻辑是通过递归遍历所有嵌套层级的folder节点,提取完成后自定义排序规则按id降序排列,完整可运行代码如下:
<?php if (file_exists('api_results.xml')) { // 正确加载本地XML文件 $xml = simplexml_load_file('api_results.xml'); $folders = []; // 递归提取所有层级folder节点 $extractFolders = function($folderNode) use (&$folders, &$extractFolders) { // 存入当前节点的id和name $folders[] = [ 'id' => (int)$folderNode->id, 'name' => (string)$folderNode->name ]; // 如果当前节点下存在parent嵌套的folder,继续递归提取 if (isset($folderNode->parent->folder)) { $extractFolders($folderNode->parent->folder); } }; // 从最外层folder节点开始递归 $extractFolders($xml->document->folder); // 按id字段降序排序 usort($folders, function($a, $b) { return $b['id'] - $a['id']; }); // 提取排序后的name列表 $sortedNames = array_column($folders, 'name'); // 输出结果 print_r($sortedNames); } else { exit('Failed to open api_results.xml.'); }
运行结果
代码执行后输出的按id降序排列的name内容为:
Array ( [0] => My Folder [1] => Contents [2] => Sub Folder [3] => Root Folder )
如果需要保留id和name的关联结构,直接输出排序后的$folders数组即可。
内容的提问来源于stack exchange,提问作者C.Felix
相关产品推荐
相关产品推荐

