如何合并多个XML文件?解决simplexml_load_file加载多文件到数组问题
我来帮你搞定这个问题!拆分大型XML文件+把多个同结构XML加载到同一个数组的需求,咱们分两步来解决:
第一步:拆分大型XML文件
因为你的XML文件太大,直接用simplexml_load_file会把整个文件塞进内存,导致加载慢甚至内存溢出。推荐用XMLReader来流式读取,逐节点处理,这样内存占用会低很多。
比如下面这个示例代码,会把大XML里的每个<query>节点拆分到单独的小XML文件里(你也可以按数量批量拆分,比如每100个query一个文件):
$reader = new XMLReader(); $reader->open('large.xml'); // 你的大型XML文件路径 $fileCounter = 1; $currentQueries = []; // 遍历XML节点 while ($reader->read()) { if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'query') { // 读取整个query节点的XML内容 $queryXml = $reader->readOuterXml(); $currentQueries[] = $queryXml; // 这里设置每50个query生成一个文件,可按需调整 if (count($currentQueries) == 50) { $outputXml = '<?xml version="1.0"?>' . "\n<queries>\n" . implode("\n", $currentQueries) . "\n</queries>"; file_put_contents("split_$fileCounter.xml", $outputXml); $fileCounter++; $currentQueries = []; } } } // 处理剩余的query if (!empty($currentQueries)) { $outputXml = '<?xml version="1.0"?>' . "\n<queries>\n" . implode("\n", $currentQueries) . "\n</queries>"; file_put_contents("split_$fileCounter.xml", $outputXml); } $reader->close();
这样拆分出来的每个小XML结构和你示例里的a.xml完全一致,都是以<queries>为根节点,包含若干<query>。
第二步:将多个拆分后的XML加载到同一个数组
你用simplexml_load_file加载后无法合并,是因为每个加载的对象是包含<queries>根节点的SimpleXMLElement,直接合并对象不行,得先把每个文件里的<query>节点转成数组,再合并到总数组里。
示例代码如下:
$mergedQueries = []; $splitFiles = glob('split_*.xml'); // 获取所有拆分后的XML文件 foreach ($splitFiles as $file) { // 加载单个拆分文件 $xml = simplexml_load_file($file); if (!$xml) { continue; // 跳过加载失败的文件 } // 把SimpleXMLElement转成关联数组(适合结构简单的XML) $xmlArray = json_decode(json_encode($xml), true); // 处理单个query的情况(如果文件里只有一个query,转数组后不会是数组形式) $queries = isset($xmlArray['query']) ? $xmlArray['query'] : []; if (!is_array($queries)) { $queries = [$queries]; } // 合并到总数组 $mergedQueries = array_merge($mergedQueries, $queries); } // 现在$mergedQueries就是所有query合并后的数组了 print_r($mergedQueries);
小提示:
- 如果你的XML里有特殊字符或者复杂结构,
json_decode(json_encode($xml), true)可能会有小问题,这时候可以用递归函数把SimpleXMLElement转成数组,或者用DOMDocument来处理。 - 拆分的时候,你可以根据自己的需求调整每个小文件包含的query数量,平衡文件数量和单个文件大小。
内容的提问来源于stack exchange,提问作者Nino
相关产品推荐
相关产品推荐

