Skip to content

Commit 1199090

Browse files
committed
bug symfony#52589 [Serializer] Fix XML attributes not added on empty node (mtarld)
This PR was merged into the 5.4 branch. Discussion ---------- [Serializer] Fix XML attributes not added on empty node | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix symfony#52385 | License | MIT Add XML namespace attributes on node whether they have chlidren or not. Commits ------- 4ee28fb [Serializer] Fix XML attributes not added on empty
2 parents b3f22f8 + 4ee28fb commit 1199090

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

src/Symfony/Component/Serializer/Encoder/XmlEncoder.php

+21-12
Original file line numberDiff line numberDiff line change
@@ -140,26 +140,22 @@ public function decode(string $data, string $format, array $context = [])
140140
// todo: throw an exception if the root node name is not correctly configured (bc)
141141

142142
if ($rootNode->hasChildNodes()) {
143-
$xpath = new \DOMXPath($dom);
144-
$data = [];
145-
foreach ($xpath->query('namespace::*', $dom->documentElement) as $nsNode) {
146-
$data['@'.$nsNode->nodeName] = $nsNode->nodeValue;
143+
$data = $this->parseXml($rootNode, $context);
144+
if (\is_array($data)) {
145+
$data = $this->addXmlNamespaces($data, $rootNode, $dom);
147146
}
148147

149-
unset($data['@xmlns:xml']);
150-
151-
if (empty($data)) {
152-
return $this->parseXml($rootNode, $context);
153-
}
154-
155-
return array_merge($data, (array) $this->parseXml($rootNode, $context));
148+
return $data;
156149
}
157150

158151
if (!$rootNode->hasAttributes()) {
159152
return $rootNode->nodeValue;
160153
}
161154

162-
return array_merge($this->parseXmlAttributes($rootNode, $context), ['#' => $rootNode->nodeValue]);
155+
$data = array_merge($this->parseXmlAttributes($rootNode, $context), ['#' => $rootNode->nodeValue]);
156+
$data = $this->addXmlNamespaces($data, $rootNode, $dom);
157+
158+
return $data;
163159
}
164160

165161
/**
@@ -344,6 +340,19 @@ private function parseXmlValue(\DOMNode $node, array $context = [])
344340
return $value;
345341
}
346342

343+
private function addXmlNamespaces(array $data, \DOMNode $node, \DOMDocument $document): array
344+
{
345+
$xpath = new \DOMXPath($document);
346+
347+
foreach ($xpath->query('namespace::*', $node) as $nsNode) {
348+
$data['@'.$nsNode->nodeName] = $nsNode->nodeValue;
349+
}
350+
351+
unset($data['@xmlns:xml']);
352+
353+
return $data;
354+
}
355+
347356
/**
348357
* Parse the data and convert it to DOMElements.
349358
*

src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php

+11
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,17 @@ public function testDecodeWithNamespace()
450450
$array = $this->getNamespacedArray();
451451

452452
$this->assertEquals($array, $this->encoder->decode($source, 'xml'));
453+
454+
$source = '<?xml version="1.0"?>'."\n".
455+
'<response xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" app:foo="bar">'.
456+
'</response>'."\n";
457+
458+
$this->assertEquals([
459+
'@xmlns' => 'http://www.w3.org/2005/Atom',
460+
'@xmlns:app' => 'http://www.w3.org/2007/app',
461+
'@app:foo' => 'bar',
462+
'#' => '',
463+
], $this->encoder->decode($source, 'xml'));
453464
}
454465

455466
public function testDecodeScalarWithAttribute()

0 commit comments

Comments
 (0)