PHP

PHP – How to Merge Two SimpleXML Objects

Problem

A recent project required that two SimpleXML Objects be merged together. It took some searching and testing with various methods through trial and error. At the end of the day a promising script was found. It seemed reasonable that the solution should be shared to help others spend less time looking. The script didn’t come attached with instructions so hopefully this will help a number of people trying to merge two SimpleXML objects.

Example

</span>

<span style="font-family: 'Tlwg Typist';">object1.xml:</span>

<span style="font-family: 'Tlwg Typist';">&lt;?xml version="1.0"?&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;general&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;name&gt;Toby&lt;/name&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;mood&gt;Happy&lt;/mood&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;location&gt;Winona&lt;/location&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;/general&gt;</span>

&nbsp;

<span style="font-family: 'Tlwg Typist';">object2.xml:</span>

<span style="font-family: 'Tlwg Typist';">&lt;?xml version="1.0"?&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;general&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;car&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;make&gt;Audi&lt;/make&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;model&gt;90&lt;/model&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;/car&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;/general&gt;</span>

&nbsp;

<span style="font-family: 'Tlwg Typist';">

Solution

</span>

<span style="font-family: 'Tlwg Typist';">&lt;?php
/**
* Pumps all child elements of second SimpleXML object into first one.
*
* @param object $xml1 SimpleXML object
* @param object $xml2 SimpleXML object
* @return void
*/
function simplexml_merge (SimpleXMLElement &amp;$xml1, SimpleXMLElement $xml2)</span>

<span style="font-family: 'Tlwg Typist';">{
// convert SimpleXML objects into DOM ones</span>

<span style="font-family: 'Tlwg Typist';">$dom1 = new DomDocument();</span>

<span style="font-family: 'Tlwg Typist';">$dom2 = new DomDocument();</span>

<span style="font-family: 'Tlwg Typist';">$dom1-&gt;loadXML($xml1-&gt;asXML());</span>

<span style="font-family: 'Tlwg Typist';">$dom2-&gt;loadXML($xml2-&gt;asXML());</span>

<span style="font-family: 'Tlwg Typist';">// pull all child elements of second XML</span>

<span style="font-family: 'Tlwg Typist';">$xpath = new domXPath($dom2);</span>

<span style="font-family: 'Tlwg Typist';">$xpathQuery = $xpath-&gt;query('/*/*');</span>

<span style="font-family: 'Tlwg Typist';">for ($i = 0; $i &lt; $xpathQuery-&gt;length; $i++)</span>

<span style="font-family: 'Tlwg Typist';">{</span>

<span style="font-family: 'Tlwg Typist';">// and pump them into first one</span>

<span style="font-family: 'Tlwg Typist';">$dom1-&gt;documentElement-&gt;appendChild(</span>

<span style="font-family: 'Tlwg Typist';">$dom1-&gt;importNode($xpathQuery-&gt;item($i), true));</span>

<span style="font-family: 'Tlwg Typist';">}</span>

<span style="font-family: 'Tlwg Typist';">$xml1 = simplexml_import_dom($dom1);</span>

<span style="font-family: 'Tlwg Typist';">}</span>

<span style="font-family: 'Tlwg Typist';">$xml1 = simplexml_load_file('object1.xml', 'SimpleXMLElement', LIBXML_NOCDATA);</span>

<span style="font-family: 'Tlwg Typist';">$xml2 = simplexml_load_file('object2.xml','SimpleXMLElement', LIBXML_NOCDATA);</span>

<span style="font-family: 'Tlwg Typist';">simplexml_merge($xml1, $xml2);</span>

<span style="font-family: 'Tlwg Typist';">$xml1-&gt;asXml('output.xml');</span>

<span style="font-family: 'Tlwg Typist';">?&gt;</span>

<span style="font-family: 'Tlwg Typist';">

Example Output

</span>

<span style="font-family: 'Tlwg Typist';">&lt;?xml version="1.0"?&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;general&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;name&gt;Toby&lt;/name&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;mood&gt;Happy&lt;/mood&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;location&gt;Winona&lt;/location&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;car&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;make&gt;Audi&lt;/make&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;model&gt;90&lt;/model&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;/car&gt;</span>

<span style="font-family: 'Tlwg Typist';">&lt;/general&gt;</span>

<span style="font-family: 'Tlwg Typist';">

Conclusion

As you can see from the example the root element is matched up by the script and the objects are merged one following the other. The project mentioned at the top of this article was large and complex and the script still kept the structure and values intact without any issues.

Side Notes

Some of the other solutions for merging two SimpleXML objects consisted of converting the objects to PHP arrays and then running a script in an attempt to join them recursively. Those scripts worked to an extent. However they had problems since PHP arrays need unique keys and XML elements can have the same tags used multiple times.

Tags :