How to compare similar XMLs with PHPUnit?
This seems to have solved the problem:
https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertXmlStringEqualsXmlString
Which version of PHPUnit is this? I'm pretty sure recent versions all support DomDocument comparisons.
Short version: Use the $doc->preserveWhiteSpace
setting to remove the whitespace, and then use $doc->C14N()
to strip comments and get a string you can compare.
OK, here's a script you can play with, note that the EOD;
lines cannot have any trailing or leading whitespace.
$x1 = <<<EOD
<responses>
<response id="12">
<foo>bar</foo>
<lorem>ipsum</lorem>
<sit>dolor</sit>
<!--This is a comment -->
</response></responses>
EOD;
$x2 = <<<EOD
<responses>
<response id="12">
<lorem>ipsum</lorem><sit>dolor</sit>
<foo>bar</foo>
<!--This is another comment -->
</response>
</responses>
EOD;
// The next block is part of the same file, I'm just making this formatting-break so that the StackOverflow syntax-highlighting system doesn't choke.
$USE_C14N = true; // Try false, just to see the difference.
$d1 = new DOMDocument(1.0);
$d2 = new DOMDocument(1.0);
$d1->preserveWhiteSpace = false;
$d2->preserveWhiteSpace = false;
$d1->formatOutput = false; // Only useful for "pretty" output with saveXML()
$d2->formatOutput = false; // Only useful for "pretty" output with saveXML()
$d1->loadXML($x1); // Must be done AFTER preserveWhiteSpace and formatOutput are set
$d2->loadXML($x2); // Must be done AFTER preserveWhiteSpace and formatOutput are set
if($USE_C14N){
$s1 = $d1->C14N(true, false);
$s2 = $d2->C14N(true, false);
} else {
$s1 = $d1->saveXML();
$s2 = $d2->saveXML();
}
echo $s1 . "\n";
echo $s2 . "\n";
Output with $USE_C14N=true;
<responses><response id="12"><foo>bar</foo><lorem>ipsum</lorem><sit>dolor</sit></response></responses>
<responses><response id="12"><lorem>ipsum</lorem><sit>dolor</sit><foo>bar</foo></response></responses>
Output with $USE_C14N=false;
<?xml version="1.0"?>
<responses><response id="12"><foo>bar</foo><lorem>ipsum</lorem><sit>dolor</sit><!--This is a comment --></response></responses>
<?xml version="1.0"?>
<responses><response id="12"><lorem>ipsum</lorem><sit>dolor</sit><foo>bar</foo><!--This is another comment --></response></responses>
Note that $doc->C14N()
might be slower, but I think it seems likely that stripping out comments is desirable. Note that all of this also assumes that whitespace in your XML isn't important, and there are probably some use-cases where that assumption isn't right...