Description
Symfony version(s) affected
6.3
Description
When using XmlEncoder::decode
on a node that does not have children and the node has a namespace defined then the namespace is not in the array even if it is needed for attributes on that node.
This results in an invalid xml when encoding it again to XML.
In the following example on how to reproduce there is a namespaced attribute xsi:noNamespaceSchemaLocation
but after reading the xml and writing it again this is now invalid xml and throws a warning when trying to read it:
PHP Warning: XMLReader::read(): test.xml:2: namespace error : Namespace prefix xsi for noNamespaceSchemaLocation on property is not defined
How to reproduce
$encoder = new XmlEncoder();
$data = $encoder->decode(
<<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<property xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://domain.com/path/to/schema.xsd" modification_timestamp="2009-11-10T10:52:16.0Z"></property>
XML,
'array'
);
var_export($data);
// array (
// '@xsi:noNamespaceSchemaLocation' => 'http://domain.com/path/to/schema.xsd',
// '@modification_timestamp' => '2009-11-10T10:52:16.0Z',
// '#' => '',
//)
echo $encode->encode($data, 'xml');
// <response xsi:noNamespaceSchemaLocation="http://domain.com/path/to/schema.xsd" modification_timestamp="2009-11-10T10:52:16.0Z"></response>
Possible Solution
The method XmlEncoder::parseXmlAttributes
could check if an attribute has a namespace and at least fetch this namespace from the $node
like it is done in XmlEncoder::decode
in case the root node has child nodes:
foreach ($xpath->query('namespace::*', $dom->documentElement) as $nsNode) {
$data['@'.$nsNode->nodeName] = $nsNode->nodeValue;
}
Additional Context
No response