Merge XML files in PHP
Since you've put an effort in, I've coded something that should work.
Note that this is untested code, but you get the idea.
It's up to you to make it into pretty functions. Make sure you understand what's going on; being able to work with the DOM will probably help you out in a lot of future scenarios. The cool thing about the DOM standard is that you have pretty much the same operations in many different programming languages/platforms.
$doc1 = new DOMDocument();
$doc1->load('1.xml');
$doc2 = new DOMDocument();
$doc2->load('2.xml');
// get 'res' element of document 1
$res1 = $doc1->getElementsByTagName('res')->item(0);
// iterate over 'item' elements of document 2
$items2 = $doc2->getElementsByTagName('item');
for ($i = 0; $i < $items2->length; $i ++) {
$item2 = $items2->item($i);
// import/copy item from document 2 to document 1
$item1 = $doc1->importNode($item2, true);
// append imported item to document 1 'res' element
$res1->appendChild($item1);
}
Combining XML files in php
Merging several files can be done something like...
function mergeFile ( DOMDocument $target, $fileName ) {
$source = new DOMDocument();
$source->load($fileName);
foreach ( $source->getElementsByTagName("row") as $row ) {
$import = $target->importNode($row, true);
$target->documentElement->appendChild($import);
}
}
$target = new DOMDocument();
$target->loadXML('<?xml version="1.0" encoding="utf-8"?><sales></sales>');
mergeFile($target, "NewFile.xml");
mergeFile($target, "NewFile1.xml");
mergeFile($target, "NewFile2.xml");
$target->save("out2.xml");
This allows you to keep on adding all of the files together and then saving them at the end.
Combine multiple XML files with PHP and wrap in new root element
Actually your source only has some minor mistakes. You create a root
document element in the target document, not the files
element in you example. Additionally your copy of the nodes in the source documents is a level to deep, you just need to import their document elements.
I modified your code a little to make it self contained and fixed the mistakes.
$files= array(
'file1.xml' =>
'<root information="file1">
<items>
<item>FOO</item>
<item>BAR</item>
</items>
</root>',
'file2.xml' =>
'<root information="file2">
<items>
<item>BAR</item>
<item>FOO</item>
</items>
</root>'
);
// create a target document with a files root
$target = new DOMDocument();
$target->appendChild($target->createElement('files'));
// iterate the source files array
foreach ($files as $name => $content) {
// load each source
$source = new DOMDocument();
$source->loadXml($content);
// if it has a document element
if ($source->documentElement) {
// copy it to the target document
$target->documentElement->appendChild(
$target->importNode($source->documentElement, TRUE)
);
}
}
$target->formatOutput = TRUE;
echo $target->saveXml();
PHP - best way to combine multiple XML files into one, then show as a webpage with XML formatting?
Using DOMDocument rather than SimpleXML allows you to do it very easily...
function mergeFile ( DOMDocument $target, $fileName ) {
$source = new DOMDocument();
$target->preserveWhiteSpace = false;
$source->load($fileName);
$import = $target->importNode($source->documentElement, true);
$target->documentElement->appendChild($import);
}
$target = new DOMDocument();
$target->formatOutput = true;
$target->preserveWhiteSpace = true;
$target->loadXML('<?xml version="1.0" encoding="utf-8"?><animals></animals>');
mergeFile($target, "dog.xml");
mergeFile($target, "cat.xml");
mergeFile($target, "rabbit.xml");
$target->loadXML($target->saveXML());
$target->save("animals.xml");
There are a few fiddles in there to ensure the format is correct, at the end it re-loads the document to create the proper layout. Also when loading the sub-documents, the spacing isn't preserved to allow the main document to sort this out.
The output file is...
<?xml version="1.0" encoding="utf-8"?>
<animals>
<animal>
<species>dog</species>
<weight>10</weight>
<length>2</length>
</animal>
<animal>
<species>rabbit</species>
<weight>0.6</weight>
<length>0.3</length>
</animal>
<animal>
<species>cat</species>
<weight>2.5</weight>
<length>1</length>
</animal>
</animals>
Combine XML Files using PHP
Since you need to merge attributes from the rain nodes in both XML, consider XSLT, the special-purpose XML transformation language. With XSLT's document()
function, you can parse from an external saved file in a current or subdirectory relative to the xsl script.
PHP can run XSLT 1.0 scripts with the php-xsl class which is enabled as an extension in .ini file. No for
loops or if
logic needed for this approach.
XSLT (save as .xsl file in same directory: alert.fcd.maricopa.gov/alert/Google/xml/) or embed as a PHP string)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/FCDMC">
<xsl:copy>
<xsl:copy-of select="rpt_info"/>
<xsl:apply-templates select="gage_rain"/>
</xsl:copy>
</xsl:template>
<xsl:template match="gage_rain">
<xsl:copy>
<xsl:variable name="curr_id" select="@id"/>
<xsl:copy-of select="@*"/>
<xsl:copy-of select="document('fcdmc_alert_return.xml')/FCDMC/return_rain[@id=$curr_id]/@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
PHP (load only the first XML as XSL handles the second XML)
// Load the XML source and XSLT file
$cd = dirname(__FILE__);
$doc = new DOMDocument();
$doc->load($cd.'/fcdmc_alert_rain_v3.xml');
$xsl = new DOMDocument;
$xsl->load($cd.'/XSLT_Script.xsl'); // OR $xsl->loadXML($xslstr);
// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// Transform XML source
$newXml = $proc->transformToXML($doc);
// Save output to file
$xmlfile = $cd.'/merged.xml';
file_put_contents($xmlfile, $newXml);
Output
<?xml version="1.0"?>
<FCDMC>
<rpt_info created="07-06-2017 11:39"/>
<gage_rain id="770" last_rpt="2017-07-06T06:00:00" min_10="0.00" min_30="0.00" hour_1="0.00" hour_3="0.00" hour_6="0.00" day_1="0.00" day_3="0.00" day_7="0.00" cytd="1.77" rainscore="1" name="Tat Momolikot Dam [TM]" lat=" 32.65120" long="-111.92830" min10="0" min30="0" hour1="0" hour3="0" hour6="0" day1="0" day3="0" day7="0"/>
<gage_rain id="775" last_rpt="2017-07-06T06:00:00" min_10="0.00" min_30="0.00" hour_1="0.00" hour_3="0.00" hour_6="0.00" day_1="0.00" day_3="0.00" day_7="0.00" cytd="1.69" rainscore="1" name="Gila R. @ Maricopa Rd. [SP]" lat=" 33.17076" long="-112.00601" min10="0" min30="0" hour1="0" hour3="0" hour6="0" day1="0" day3="0" day7="0"/>
<gage_rain id="780" last_rpt="2017-07-06T06:00:00" min_10="0.00" min_30="0.00" hour_1="0.00" hour_3="0.00" hour_6="0.00" day_1="0.00" day_3="0.00" day_7="0.00" cytd="1.22" rainscore="1" name="Gila River at Olberg [SP]" lat=" 33.08706" long="-111.68700" min10="0" min30="0" hour1="0" hour3="0" hour6="0" day1="0" day3="0" day7="0"/>
<gage_rain id="785" last_rpt="2017-07-06T06:00:00" min_10="0.00" min_30="0.00" hour_1="0.00" hour_3="0.00" hour_6="0.00" day_1="0.00" day_3="0.00" day_7="0.00" cytd="2.13" rainscore="1" name="Santa Cruz R. @ SR 84 [SP]" lat=" 32.87952" long="-111.82895" min10="0" min30="0" hour1="0" hour3="0" hour6="0" day1="0" day3="0" day7="0"/>
<gage_rain id="795" last_rpt="2017-07-06T06:00:00" min_10="0.00" min_30="0.00" hour_1="0.00" hour_3="0.00" hour_6="0.00" day_1="0.00" day_3="0.00" day_7="0.00" cytd="0.43" rainscore="1" name="Greene Wash @ SR 84 [SP]" lat=" 32.87946" long="-111.93369" min10="0" min30="0" hour1="0" hour3="0" hour6="0" day1="0" day3="0" day7="0"/>
...
Related Topics
PHP Files Are Downloaded by Browser Instead of Processed by Local Dev Server (Mamp)
How to Perform an Action Every 5 Results
How to Make a Cascading Drop Down List in PHP Using Jquery
PHP - Merge Two Arrays (Same-Length) into One Associative
PHP Sample Script for Pagination
Multiple Replace (Probably Preg_Replace) of Same String with Array
Image - Upload Not Responding, No Access to $_Files
Which Coding Style You Use for Ternary Operator
Return PHP Object by Index Number (Not Name)
Retrieve (Or Simulate) Full Query from Pdo Prepared Statement
Trying to Access Array Offset on Value of Type Bool
Do I Really Need to Do MySQL_Close()
Enabling 'Strict_Types' Globally in PHP 7
How to Obtain Anchor Part of Url After # in PHP
Tactics for Using PHP in a High-Load Site
PHP Best Practices for User Authentication and Password Security