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...