I want to compare 2 big xml files and retrieve the differences. Like ExamXML and DiffDog do. The solution I found was cycling through all child nodes of each file simultaneously and check if they are equal. But I have no idea how to achieve that... How can I loop through all child nodes and their properties? H开发者_StackOverflow社区ow can I check if the first element of the first file is equal to the first element of the second file, the second element of the first file is equal to the second element of the second file and so on?
Do yo have a better idea to compare 2 xml files?
I was looking for something to compare two XML like you, and I found this solution that works very well.
http://www.jevon.org/wiki/Comparing_Two_SimpleXML_Documents
I hope that helps to someone.
Have you looked at using XPath at all? Seems like an easy way to grab all of the child nodes. Then you'd be able to loop through the nodes and compare the attributes/textContent.
This might be a very alternative solution for you but this is how I would do it.
First, I'd try to get the format into something much more manageable like an array so I would convert the XML to an array.
http://www.bytemycode.com/snippets/snippet/445/
This is some simple code to do just that.
Then PHP has an array_diff() function that can show you the differences.
http://www.php.net/manual/en/function.array-diff.php
This may or may not work for you considering what you need to do with the differences but if you're looking to just identify and act upon them this might be a very quick solution to your problem.
Try the xmldiff extension
http://pecl.php.net/xmldiff
It's based on the same library as the perl module DifferenceMarkup, you'll get a diff XML document and can even merge then.
//Child by Child XML files comparison in PHP
//Returns an array of non matched children in variable &$reasons
$reasons = array();
$xml1 = new SimpleXMLElement(file_get_contents($xmlFile1));
$xml2 = new SimpleXMLElement(file_get_contents($xmlFile2));
$result = XMLFileComparison($xml1, $xml2, $reasons);
/**
* XMLFileComparison
* Discription :- This function compares XML files. Returns array
* of nodes do not match in pass by reference parameter
* @param $xml1 Object Node Object
* @param $xml2 Object Node Object
* @param &$reasons Array pass by reference
* returns array of nodes do not match
* @param $strict_comparison Bool default False
* @return bool <b>TRUE</b> on success or array of strings on failure.
*/
function XMLFileComparison(SimpleXMLElement $xml1, SimpleXMLElement $xml2, &$reasons, $strict_comparison = false)
{
static $str;
// compare text content
if ($strict_comparison) {
if ("$xml1" != "$xml2") return "Values are not equal (strict)";
} else {
if (trim("$xml1") != trim("$xml2"))
{
return " Values are not equal";
}
}
// get all children
$XML1ChildArray = array();
$XML2ChildArray = array();
foreach ($xml1->children() as $b) {
if (!isset($XML1ChildArray[$b->getName()]))
$XML1ChildArray[$b->getName()] = array();
$XML1ChildArray[$b->getName()][] = $b;
}
foreach ($xml2->children() as $b) {
if (!isset($XML2ChildArray[$b->getName()]))
$XML2ChildArray[$b->getName()] = array();
$XML2ChildArray[$b->getName()][] = $b;
}
//print_r($XML1ChildArray);
//print_r($XML2ChildArray);
// cycle over children
if (count($XML1ChildArray) != count($XML2ChildArray)) return "mismatched children count";// Second File has less or more children names (we don't have to search through Second File's children too)
foreach ($XML1ChildArray as $child_name => $children) {
if (!isset($XML2ChildArray[$child_name])) return "Second file does not have child $child_name"; // Second file has none of this child
if (count($XML1ChildArray[$child_name]) != count($XML2ChildArray[$child_name])) return "mismatched $child_name children count"; // Second file has less or more children
print_r($child_name);
foreach ($children as $child) {
// do any of search2 children match?
$found_match = false;
//$reasons = array();
foreach ($XML2ChildArray[$child_name] as $id => $second_child) {
$str = $str.$child_name.($id+1)."/"; // Adding 1 to $id to match with XML data nodes numbers
//print_r($child, $second_child);
// recursive function call until reach to the end of node
if (($r = XMLFileComparison($child, $second_child, $reasons, $strict_comparison)) === true) {
// found a match: delete second
$found_match = true;
unset($XML2ChildArray[$child_name][$id]);
$str = str_replace($child_name.($id+1)."/", "", $str);
break;
}
else {
unset($XML2ChildArray[$child_name][$id]);
$reasons[$str] = $r;
$str = str_replace($child_name.($id+1)."/", "", $str);
break;
}
}
}
}
return True;
}
精彩评论