I would like to merge two XML documents. They are from two distinct web services. Each XML documents states how many books it holds in the node. I would like the total of (from each XML document) to be added and appended to the resulting merged XML document.
PHP code merging the documents:
<?php
header('Content-type: text/xml');
$xmlDom1 = new DOMDocument();
$xmlString = '';
foreach ( file('1.xml') as $node ) {
$xmlString .= trim($node);
}
$xmlDom1->loadXML($xmlString);
$xmlDom2 = new DOMDocument();
$xmlString = '';
foreach ( file('2.xml') as $node ) {
$xmlString .= trim($node);
}
$xmlDom2->loadXML($xmlString);
//merge doms
$xmlRoot = $xmlDom1->documentElement;
foreach ( $xmlDom2->documentElement->childNodes as $node2 ) {
$node = $xmlDom1->importNode($node2,true);
$xmlRoot->appendChild($node);
} echo $xmlDom1->saveXML();?>
First XML document:
<?xml version="1.0"?>
<catalog>
<NumberOfResult>2</NumberOfResult>
<book>
<bookid>1</bookid>
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book>
<bookid>2</bookid>
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
</catalog>
Second XML document:
<?xml version="1.0"?>
<catalog>
<NumberOfResult>1</NumberOfResult>
<book>
<bookid>3</bookid>
<author>Galos, Mike</author>
<title>Visual Studio 7: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>49.95</price>
<publish_date>2001-04-16</publish_date>
<description>Microsoft Visual Studio 7 is explored in depth,
looking at how Visual Basic, Visual C++, C#, and ASP+ are
integrated into a comprehensive development
environment.</description>
</book>
</catalog>
Save the content of your XML documents into variables, e.g. $xmlDocument1, 2, 3...
Use str_replace (http://www.php.net/manual/de/function.str-replace.php) and delete from the first document.
$output_new = str_replace("</catalog>", "", $xmlDocument1);
Then use it for each (use for each!) to remove it from every further document (or just the second one):
$output_new = $output_new . str_replace("<catalog>", "", $xmlDocument[$i]);
$output_new = $output_new . str_replace("</catalog>", "", $xmlDocument[$i]);
$i is the value you set in your for each which shall increase +1 every loop.
At the end, add :
$output_new = $output_new . '</catalog>';
And last but not least, write it to a new .xml file:
$xmlDocument_new = fopen("merged.xml","w");
fwrite($xmlDocument_new, $output_new);
You can also shorten the upper str_replace (in the loop) with an array but I think this is better visualized for you. Give it a try. Good luck!
You got two tasks here. Import the book nodes from several XML documents into one and add the count as element before them.
So first create a target document and add a catalog node:
$dom = new DOMDocument();
$catalog = $dom->appendChild($dom->createElement('catalog'));
Next load each source document, fetch the book nodes and import them to the target document.
foreach ($xmls as $xml) {
$srcDom = new DOMDocument();
$srcDom->loadXml($xml);
$xpath = new DOMXpath($srcDom);
foreach ($xpath->evaluate('/catalog/book') as $book) {
$catalog->appendChild($dom->importNode($book, TRUE));
}
}
Now that all book nodes are in the target document, you can use Xpath to count them.
$xpath = new DOMXpath($dom);
$count = $dom->createElement('NumberOfResult');
$count->appendChild(
$dom->createTextNode(
$xpath->evaluate('count(/catalog/books)')
)
);
$catalog->insertBefore($count, $catalog->firstChild);
Live Demo: https://eval.in/135143