php - Combine external XML files into one and orderby -
i have following php function combine multiple external xml files 1 file:
<?php function combinexml($file) { global $xmlstr; $xml = simplexml_load_file($file); foreach($xml $element) $xmlstr .= $element->asxml(); } $files[] = "file1.xml"; $files[] = "file2.xml"; $xmlstr = '<productitems>'; foreach ($files $file) combinexml($file); $xmlstr .= '</productitems>'; $xml = simplexml_load_string($xmlstr); $bytes = file_put_contents("output.xml", $xml->asxml()); ?>
is possible re-order feed? having last modified on top? order lastmodified file system date.
you did not provide xml examples let's assume simple structures:
$xmls = [ '<productitems> <item> <title>item 1</title> <lastmodified>1</lastmodified> </item> </productitems>', '<productitems> <item> <title>item 2</title> <lastmodified>2</lastmodified> </item> </productitems>' ];
merging xmls
i prefer using dom. (it's easier, because here no automagic mapping).
first create target document , add document element node:
$merged = new domdocument(); $merged->appendchild($merged->createelement('productitems'));
next iterate xmls, load them doms , copy child nodes of document element target document.
foreach ($xmls $xml) { $source = new domdocument(); $source->loadxml($xml); foreach ($source->documentelement->childnodes $node) { $merged->documentelement->appendchild( $merged->importnode($node, true) ); } }
allow formatting , save merged xml:
$merged->formatoutput = true; echo $merged->savexml();
output:
<?xml version="1.0"?> <productitems> <item> <title>item 1</title> <modified>1</modified> </item> <item> <title>item 2</title> <modified>2</modified> </item> </productitems>
working files
if you're working files have use domdocument::load()
, domdocument::save()
. domdocument::loadxml()/savexml()
xml strings.
sorting nodes
fetch item
nodes source document using xpath , convert node list array:
$xpath = new domxpath($merged); $products = iterator_to_array($xpath->evaluate('//item'));
sort array using usort
. using xpath, can fetch data in context of node:
usort( $products, function($nodeone, $nodetwo) use ($xpath) { return strnatcmp( $xpath->evaluate('string(modified)', $nodetwo), $xpath->evaluate('string(modified)', $nodeone) ); } );
create target document , copy nodes it:
$sorted= new domdocument(); $sorted->appendchild($sorted->createelement('productitems')); foreach ($products $node) { $sorted->documentelement->appendchild( $sorted->importnode($node, true) ); } $sorted->formatoutput = true; echo $sorted->savexml();
output:
<?xml version="1.0"?> <productitems> <item> <title>item 2</title> <modified>2</modified> </item> <item> <title>item 1</title> <modified>1</modified> </item> </productitems>