Реализация алгоритма нормализации XML для СМЭВ 3?
Для будущих искателей: вот такой монстрик у меня получился (PHP 7.1). Он проходит все проверки из МР 3.5, но, возможно, некоторых нюансов не учитывает.<?php
$in = new DOMDocument();
$in->load($argv[1]);

$out = new XMLWriter();
$out->openMemory();

$index = 0;
$stack = [null, [$in->documentElement, []]];
while (count($stack)) {
	$item = array_pop($stack);
	if ($item === null) {
		$out->text('');
		$out->endElement();
		continue;
	}
	[$node, $nsList] = $item;
	if ($node->nodeType == XML_ELEMENT_NODE) {
		// Let the magic begin! ;)
		// The element itself.
		if ($node->namespaceURI !== null) {
			$thisLevel = false;
			if (($nsList[$node->namespaceURI] ?? null) === null) {
				$thisLevel = true;
				$nsList[$node->namespaceURI] = 'ns' . ++$index;
			}
			$out->startElement("{$nsList[$node->namespaceURI]}:{$node->localName}");
			if ($thisLevel) {
				$out->writeAttribute("xmlns:{$nsList[$node->namespaceURI]}", $node->namespaceURI);
			}
		}
		else {
			$out->startElement($node->localName);
		}
		// Attributes.
		$attrs = iterator_to_array($node->attributes);
		usort($attrs, function($a, $b) {
			if ($a->namespaceURI !== null && $b->namespaceURI === null) return -1;
			else if ($a->namespaceURI === null && $b->namespaceURI !== null) return 1;
			else return strcmp($a->namespaceURI, $b->namespaceURI) ?: strcmp($a->localName, $b->localName);
		});
		foreach ($attrs as $attr) {
			if ($attr->namespaceURI !== null && ($nsList[$attr->namespaceURI] ?? null) === null) {
				$nsList[$attr->namespaceURI] = 'ns' . ++$index;
				$out->writeAttribute("xmlns:{$nsList[$attr->namespaceURI]}", $attr->namespaceURI);
			}
		}
		foreach ($attrs as $attr) {
			if ($attr->namespaceURI !== null) {
				$out->writeAttribute("{$nsList[$attr->namespaceURI]}:{$attr->localName}", $attr->nodeValue);
			}
			else {
				$out->writeAttribute($attr->localName, $attr->nodeValue);
			}
		}
	}
	else if ($node->nodeType == XML_TEXT_NODE && strlen(trim($node->nodeValue))) {
		$out->text($node->nodeValue);
	}

	if ($node->lastChild !== null) {
		$stack[] = null;
		for ($node = $node->lastChild; $node !== null; $node = $node->previousSibling) {
			$stack[] = [$node, $nsList];
		}
	}
}

echo $out->outputMemory(), "\n";

?>
Моя реализация алгоритма на PHP:

https://github.com/Danbka/smev-transform