I have 2 files 1.xml
and 2.xml
both having similar structure and I would like to have one. I tried many solutions but I had errors only - frankly speaking I have no idea how those scripts worked.
1.xml
:
<res> <items total="180"> <item> <id>1</id> <title>Title 1</title> <author>Author 1</author> </item> ... </items> </res>
2.xml
:
<res> <items total="123"> <item> <id>190</id> <title>Title 190</title> <author>Author 190</author> </item> ... </items> </res>
I would like to create a new file merged.xml
with the following structure
<res> <items total="303"> <item> <id>1</id> <title>Title 1</title> <author>Author 1</author> </item> ... //items from 1.xml <item> <id>190</id> <title>Title 190</title> <author>Author 190</author> </item> ... //items from 2.xml </items> </res>
How should I do that? Can you explain me the way to do it? How can I do it with more files? Thanks
Edit
What I tried?
<?php function mergeXML(&$base, $add) { if ( $add->count() != 0 ) $new = $base->addChild($add->getName()); else $new = $base->addChild($add->getName(), $add); foreach ($add->attributes() as $a => $b) { $new->addAttribute($a, $b); } if ( $add->count() != 0 ) { foreach ($add->children() as $child) { mergeXML($new, $child); } } } $xml = mergeXML(simplexml_load_file('1.xml'), simplexml_load_file('2.xml')); echo $xml->asXML(merged.xml); ?>
EDIT2
Following Torious advice I looked into DOMDocument manual and found an example:
function joinXML($parent, $child, $tag = null) { $DOMChild = new DOMDocument; $DOMChild->load($child); $node = $DOMChild->documentElement; $DOMParent = new DOMDocument; $DOMParent->formatOutput = true; $DOMParent->load($parent); $node = $DOMParent->importNode($node, true); if ($tag !== null) { $tag = $DOMParent->getElementsByTagName($tag)->item(0); $tag->appendChild($node); } else { $DOMParent->documentElement->appendChild($node); } return $DOMParent->save('merged.xml'); } joinXML('1.xml', '2.xml')
But it creates wrong xml file:
<res> <items total="180"> <item> <id>1</id> <title>Title 1</title> <author>Author 1</author> </item> ... </items> <res> <items total="123"> <item> <id>190</id> <title>Title 190</title> <author>Author 190</author> </item> ... </items> </res> </res>
And I cannot use this file properly. I need correct structure and here I have kind of pasting one file into another. I would like to "paste" only item's not all tags. What should I change?
EDIT3
here is an answer - based on Torious answer - just adapted it to my needs - check //edited
$doc1 = new DOMDocument(); $doc1->load('1.xml'); $doc2 = new DOMDocument(); $doc2->load('2.xml'); // get 'res' element of document 1 $res1 = $doc1->getElementsByTagName('items')->item(0); //edited res - items // 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); } $doc1->save('merged.xml'); //edited -added saving into xml file
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); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With