Задача про вычисление хэша XML-документа

Предыстория

В своей практике я часто имею дело с разными сервисами и АПИ, которые они предоставляют. И вот однажды выпала мне нелёгкая доля написать клиента для одного древнего сервиса. Почему нелёгкая? Да потому, что сервис принимал и отправлял XML, а каждый запрос-ответ должен был быть подписан и проверен слепком по содержимому плюс пароль. И проверен не просто абы как, а слепком именно по содержимому XML.

Задача

Вычислить хэш XML-документа без привязки элементов и атрибутов к положению в документе. То есть, если какой-то элемент содержит дочерние элементы или атрибуты, то порядок их следования не должен влиять на результат.

PHP-код

<?php

$xmlDocs = [
    '<?xml version="1.0"?><Element><Sub1 attr1="foo" attr2="bar" /><Sub2 /></Element>',
    '<?xml version="1.0"?><Element><Sub1 attr1="foo" attr2="baz" /><Sub2 /></Element>',
    '<?xml version="1.0"?><Element><Sub2 /><Sub1 attr2="bar" attr1="foo" /></Element>',
];

$xmlHash = function($xml) {
    // Вычисляем хэш
};

foreach($xmlDocs as $i => $xml) {
    echo "Doc $i: ", $xmlHash($xml), PHP_EOL;
}

Правильный результат работы:

Doc 0: 2d00e96b8b7d9e32ddadc4ed9df31f3e
Doc 1: 677bf7ef88611ad76695dffdd06194c6
Doc 2: 2d00e96b8b7d9e32ddadc4ed9df31f3e

Первый и второй документ имеют разный хэш, потому что отличаются содержимым атрибутов. Но первый и третий равны, потому что порядок следования подэлементов не влияет на результат.

Хорошая задача, мне понравилась. Оставлю отзыв!