diff --git a/src/Xml/Dom/Manipulator/Document/optimize_namespaces.php b/src/Xml/Dom/Manipulator/Document/optimize_namespaces.php index a1c1df7..1f351f2 100644 --- a/src/Xml/Dom/Manipulator/Document/optimize_namespaces.php +++ b/src/Xml/Dom/Manipulator/Document/optimize_namespaces.php @@ -9,6 +9,7 @@ use function Psl\Vec\map; use function Psl\Vec\sort; use function Psl\Vec\values; +use function VeeWee\Xml\Dom\Builder\xmlns_attribute; use function VeeWee\Xml\Dom\Locator\Xmlns\recursive_linked_namespaces; use function VeeWee\Xml\Dom\Manipulator\Xmlns\rename_element_namespace; @@ -24,6 +25,8 @@ function optimize_namespaces(\DOM\XMLDocument $document, string $prefix = 'ns'): ))); foreach (sort($namespaceURIs) as $index => $namespaceURI) { + $currentPrefix = $prefix . ((string) ($index+1)); + xmlns_attribute($currentPrefix, $namespaceURI)($documentElement); rename_element_namespace($documentElement, $namespaceURI, $prefix . ((string) ($index+1))); } } diff --git a/src/Xml/Dom/Manipulator/Xmlns/rename_element_namespace.php b/src/Xml/Dom/Manipulator/Xmlns/rename_element_namespace.php index ab21156..0229941 100644 --- a/src/Xml/Dom/Manipulator/Xmlns/rename_element_namespace.php +++ b/src/Xml/Dom/Manipulator/Xmlns/rename_element_namespace.php @@ -5,42 +5,42 @@ namespace VeeWee\Xml\Dom\Manipulator\Xmlns; use VeeWee\Xml\Exception\RuntimeException; -use function VeeWee\Xml\Dom\Builder\xmlns_attribute; -use function VeeWee\Xml\Dom\Predicate\is_element; +use function VeeWee\Xml\Dom\Locator\Attribute\attributes_list; +use function VeeWee\Xml\Dom\Locator\Element\children; use function VeeWee\Xml\Dom\Predicate\is_xmlns_attribute; /** * @throws RuntimeException * @param non-empty-string $newPrefix */ -function rename_element_namespace(\DOM\Element $root, string $namespaceURI, string $newPrefix): void +function rename_element_namespace(\DOM\Element $element, string $namespaceURI, string $newPrefix): void { + children($element)->forEach( + static fn (\DOM\Element $child) => rename_element_namespace($child, $namespaceURI, $newPrefix) + ); - $recurse = function (\DOM\Element $element) use (&$recurse, $namespaceURI, $newPrefix): void { - foreach ($element->childNodes as $child) { - if (is_element($child)) { - $recurse($child); - } + attributes_list($element)->forEach(static function (\DOM\Attr $attr) use ($namespaceURI, $newPrefix, $element) { + if ($attr->namespaceURI === $namespaceURI) { + $attr->rename($namespaceURI, $newPrefix . ':' . $attr->localName); } - $hasXmlnsAttribute = false; - foreach ($element->attributes as $attr) { - if ($attr->namespaceURI === $namespaceURI) { - $attr->rename($namespaceURI, $newPrefix . ':' . $attr->localName); - } - - if (is_xmlns_attribute($attr) && $attr->value === $namespaceURI) { + if (is_xmlns_attribute($attr) && $attr->value === $namespaceURI) { + try { $attr->rename($attr->namespaceURI, 'xmlns:' . $newPrefix); - } - } - if ($element->namespaceURI === $namespaceURI) { - $element->rename($namespaceURI, $newPrefix . ':' . $element->localName); + } catch (\DOMException $e) { + if ($e->getCode() === \DOM\INVALID_MODIFICATION_ERR) { + // Remove the attribute that would become a duplicate + $element->removeAttributeNode($attr); + } else { + throw $e; + } + } + $attr->rename($attr->namespaceURI, 'xmlns:' . $newPrefix); } - }; + }); - $recurse( - // TODO - should become : xmlns_attribute($newPrefix, $namespaceURI)($root), - $root - ); + if ($element->namespaceURI === $namespaceURI) { + $element->rename($namespaceURI, $newPrefix . ':' . $element->localName); + } } diff --git a/tests/Xml/Dom/Configurator/OptimizeNamespacesTest.php b/tests/Xml/Dom/Configurator/OptimizeNamespacesTest.php index f38d409..8f2224e 100644 --- a/tests/Xml/Dom/Configurator/OptimizeNamespacesTest.php +++ b/tests/Xml/Dom/Configurator/OptimizeNamespacesTest.php @@ -52,7 +52,7 @@ public function provideXmls() EOXML, << + EOXML, @@ -64,7 +64,7 @@ public function provideXmls() EOXML, << + EOXML, diff --git a/tests/Xml/Dom/Manipulator/Document/OptimizeNamespacesTest.php b/tests/Xml/Dom/Manipulator/Document/OptimizeNamespacesTest.php index 01ffb87..a775cb7 100644 --- a/tests/Xml/Dom/Manipulator/Document/OptimizeNamespacesTest.php +++ b/tests/Xml/Dom/Manipulator/Document/OptimizeNamespacesTest.php @@ -106,7 +106,7 @@ public function provideXmls() EOXML, << + Jos Jaak Jul