Skip to content

Commit

Permalink
Optimize namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
veewee committed Apr 1, 2024
1 parent e066614 commit e764516
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 27 deletions.
3 changes: 3 additions & 0 deletions src/Xml/Dom/Manipulator/Document/optimize_namespaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)));
}
}
48 changes: 24 additions & 24 deletions src/Xml/Dom/Manipulator/Xmlns/rename_element_namespace.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
4 changes: 2 additions & 2 deletions tests/Xml/Dom/Configurator/OptimizeNamespacesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function provideXmls()
</schema>
EOXML,
<<<EOXML
<ns1:schema xmlns:ns1="http://www.w3.org/2001/XMLSchema" targetNamespace="http://soapinterop.org/store1">
<ns1:schema targetNamespace="http://soapinterop.org/store1" xmlns:ns1="http://www.w3.org/2001/XMLSchema">
<ns1:include schemaLocation="./store1.xsd"/>
</ns1:schema>
EOXML,
Expand All @@ -64,7 +64,7 @@ public function provideXmls()
</schema>
EOXML,
<<<EOXML
<ns1:schema xmlns:ns1="http://www.w3.org/2001/XMLSchema" targetNamespace="http://soapinterop.org/store1">
<ns1:schema targetNamespace="http://soapinterop.org/store1" xmlns:ns1="http://www.w3.org/2001/XMLSchema">
<ns1:include schemaLocation="./store1.xsd"/>
</ns1:schema>
EOXML,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public function provideXmls()
</foo>
EOXML,
<<<EOXML
<foo xmlns:ns1="http://a" xmlns:ns2="http://z" version="1.9" target="universe">
<foo version="1.9" target="universe" xmlns:ns1="http://a" xmlns:ns2="http://z">
<item id="1" sku="jos">Jos</item>
<item sku="jaak" id="2">Jaak</item>
<item ns1:sku="jaak" ns2:id="3">Jul</item>
Expand Down

0 comments on commit e764516

Please sign in to comment.