If I have a DOMDocument and I would like to parse it into a string, how do I ensure that the attributes will be sorted in some deterministic/normalized order (lexicographically based on the attribute name would be nice)?
For example how can I make this print equal
instead of notequal
?
$dom = new DOMDocument();
$dom->loadXML('<tag a="a" b="b"/>');
$dom2 = new DOMDocument();
$dom2->loadXML('<tag b="b" a="a"/>');
echo $dom->saveXML() === $dom2->saveXML() ? "equal" : "notequal";
According to the documentation, saveXML
only supported option is LIBXML_NOEMPTYTAG
.
DOMNode::C14N()
canonicalizes nodes to a string.
$expected = new DOMDocument();
$expected->loadXML('<tag a="a" b="b"/>');
$actual = new DOMDocument();
$actual->loadXML('<tag b="b" a="a"/>');
echo $expected->C14N() === $actual->C14N() ? "equal" : "notequal";
Output:
equal
If you're write unit tests - PHPUnit has specific assertions for XML.
assertXmlFileEqualsXmlFile()
assertXmlStringEqualsXmlFile()
assertXmlStringEqualsXmlString()