-3

I am new to PHP programming and would appreciate whatever help i can get. I have an Xml file that looks like below..

<?xml version="1.0" encoding="UTF-8"?> <results> <test external_id="123"> <result>p</result> </test> <test external_id="1237"> <result>p</result> </test> <test external_id="234"> <result>p</result> </test> <test external_id="678"> <result>p</result> </test> </results> 

The XML file is generated from a testrun. Now sometimes the test could break and would restart generating another xml file which might contain similar values as generated in the first xml file. For example, Xml file 2 might contain the following values

<?xml version="1.0" encoding="UTF-8"?> <results> <test external_id="412"> <result>p</result> </test> <test external_id="234"> <result>p</result> </test> <test external_id="123"> <result>p</result> </test> <test external_id="745"> <result>p</result> </test> </results> 

I need to write a PHP script to merge the different XML files generated into a single XML file without duplicates. Only one occurrence of (test external_id = "XXX")should be in the final xml file. There could be more than 2 XML files generated during the test run. I have searched through the various solutions given on stackoverflow but can't get it. I have been able to merge the files but the duplicates are still there.What I have written so far. Thanks for your anticipated help.

<?php $doc1 = new DOMDocument(); $doc1->load('11.xml'); $doc2 = new DOMDocument(); $doc2->load('12.xml'); // get 'results' element of document 1 $res1 = $doc1->getElementsByTagName('results')->item(0); // iterate over 'testcase' elements of document 2 $items2 = $doc2->getElementsByTagName('test'); 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'); //saving into xml file $seen=array(); $doc3 = new DOMDocument(); $doc3->load('merged.xml'); $results = $doc3->getElementsByTagName('test'); foreach($results as $test){ //$key=$doc3->$test; if (isset($seen[$test])) { unset($doc3->$test); }else{ $seen[$test]=1; } } echo $doc3->asXML(); ?> 
7
  • 2
    Possible duplicate of Merge XML files in PHP Commented Jan 25, 2018 at 9:16
  • 2
    Is this a homework? Commented Jan 25, 2018 at 9:17
  • "I need to write a PHP script ..." Then do that. Post your code if you have any and get stuck somewhere Commented Jan 25, 2018 at 9:19
  • @WaqasBukhary, I have tried that and it actually merges the files but with duplicates. I need only one occurrence of each test. How can I modify the script to remove duplicates Commented Jan 25, 2018 at 9:20
  • $seen=array(); $doc3 = new DOMDocument(); $doc3->load('merged.xml'); $results = $doc3->getElementsByTagName('test'); foreach($results as $test){ //$key=$doc3->$test; if (isset($seen[$test])) { unset($doc3->$test); }else{ $seen[$test]=1; } } echo $doc3->asXML(); Commented Jan 25, 2018 at 9:25

1 Answer 1

0

With the two files you have, it's easier to take 1 file and add the elements in from the other. First it checks if the node already exists (using XPath and counting the number of elements that have the same ID). If the node doesn't already exist, it has to first import the node from the one document to the other and then add it to the root element.

$doc1 = new DOMDocument(); $doc1->load('NewFile.xml'); // Change file names as needed. $xp = new DOMXPath($doc1); $doc2 = new DOMDocument(); $doc2->load('NewFile1.xml'); $test1 = $doc2->getElementsByTagName('test'); foreach ( $test1 as $testItem ) { $id = $testItem->getAttribute('external_id'); if ( $xp->evaluate("count(//test[@external_id='{$id}'])") == 0 ) { $copyNode = $doc1->importNode($testItem, true); $doc1->documentElement->appendChild($copyNode); } } echo $doc1->saveXML(); 

XPath isn't the quickest thing to run, but it's easier to do it this way rather than having to loop through the document (IMHO).

This isn't the best solution if you have large files as it holds all the content in memory for both documents.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.