-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Inherit XMLNS during encoding like we did in v3
- Loading branch information
Showing
11 changed files
with
110 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace VeeWee\Xml\Dom\Builder; | ||
|
||
use Closure; | ||
use Dom\Element; | ||
use VeeWee\Xml\Xmlns\Xmlns; | ||
|
||
/** | ||
* @return Closure(Element): Element | ||
*/ | ||
function default_xmlns_attribute(string $namespaceURI): Closure | ||
{ | ||
return static function (Element $node) use ($namespaceURI): Element { | ||
$node->setAttributeNS(Xmlns::xmlns()->value(), 'xmlns', $namespaceURI); | ||
|
||
return $node; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace VeeWee\Xml\Dom\Predicate; | ||
|
||
use function Psl\Regex\matches; | ||
|
||
function is_prefixed_node_name(string $nodeName): bool | ||
{ | ||
return matches($nodeName, '/^[^:]+:[^:]+$/'); | ||
Check failure on line 11 in src/Xml/Dom/Predicate/is_prefixed_node_name.php
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
src/Xml/Encoding/Internal/Encoder/Builder/xmlns_inheriting_element.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace VeeWee\Xml\Encoding\Internal\Encoder\Builder; | ||
|
||
use Closure; | ||
use Dom\Element; | ||
use Dom\XMLDocument; | ||
use Webmozart\Assert\Assert; | ||
use function VeeWee\Xml\Dom\Builder\default_xmlns_attribute; | ||
use function VeeWee\Xml\Dom\Builder\element as elementBuilder; | ||
use function VeeWee\Xml\Dom\Builder\namespaced_element as namespacedElementBuilder; | ||
use function VeeWee\Xml\Dom\Predicate\is_element; | ||
use function VeeWee\Xml\Dom\Predicate\is_prefixed_node_name; | ||
|
||
/** | ||
* This function can create element nodes that inherit the local xmlns namespace of their parent if none is configured. | ||
* | ||
* @param list<Closure(Element): Element> $children | ||
* @param array<string, string> $namespaces | ||
* | ||
* @return Closure(Element): Element | ||
*/ | ||
function xmlns_inheriting_element(string $name, array $children, ?array $namespaces = []): Closure | ||
{ | ||
return function (XMLDocument|Element $parent) use ($namespaces, $name, $children): Element { | ||
|
||
$defaultNamespace = $namespaces[''] ?? null; | ||
|
||
// These rules apply for non prefixed elements only: | ||
// If no local namespace has been defined: lookup the default local namespace of the closest parent element. | ||
// Use that specific local namespace to create the element if one could be found. | ||
// Otherwise, just create a non-namespaced element. | ||
if (!is_prefixed_node_name($name)) { | ||
// Try to find the inherited default XMLNS for non prefixed elements without a desired local namespace. | ||
if ($defaultNamespace === null && is_element($parent)) { | ||
$defaultNamespace = $parent->lookupNamespaceURI(''); | ||
} | ||
|
||
return $defaultNamespace !== null | ||
? namespacedElementBuilder($defaultNamespace, $name, ...$children)($parent) | ||
: elementBuilder($name, ...$children)($parent); | ||
} | ||
|
||
// Prefixed elements can be created as regular elements: | ||
// The configured xmlns attributes will be added by the $children. | ||
// If a local namespace is configured, make sure to register it on the node manually. | ||
[$prefix] = explode(':', $name); | ||
$prefixedNamespace = $namespaces[$prefix] ?? (is_element($parent) ? $parent->lookupNamespaceURI($prefix) : null); | ||
|
||
Assert::notNull($prefixedNamespace, 'No namespace URI could be found for prefix: '.$prefix); | ||
|
||
$defaultXmlns = $defaultNamespace !== null ? [default_xmlns_attribute($defaultNamespace)] : []; | ||
return namespacedElementBuilder( | ||
$prefixedNamespace, | ||
$name, | ||
...$defaultXmlns, | ||
...$children, | ||
)($parent); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters