diff --git a/UPGRADE-4.1.md b/UPGRADE-4.1.md
index d76e3a3796188..e197d7bcc0066 100644
--- a/UPGRADE-4.1.md
+++ b/UPGRADE-4.1.md
@@ -74,6 +74,11 @@ SecurityBundle
* The `SecurityUserValueResolver` class is deprecated, use
`Symfony\Component\Security\Http\Controller\UserValueResolver` instead.
+Serializer
+----------
+
+ * Decoding XML with `XmlEncoder` now ignores comment node types by default.
+
Translation
-----------
diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md
index a4e8bf499f5c6..d45e771e610b8 100644
--- a/src/Symfony/Component/Serializer/CHANGELOG.md
+++ b/src/Symfony/Component/Serializer/CHANGELOG.md
@@ -11,6 +11,8 @@ CHANGELOG
* added optional `bool $escapeFormulas = false` argument to `CsvEncoder::__construct`
* added `AbstractObjectNormalizer::setMaxDepthHandler` to set a handler to call when the configured
maximum depth is reached
+* added optional `int[] $ignoredNodeTypes` argument to `XmlEncoder::__construct`. XML decoding now
+ ignores comment node types by default.
4.0.0
-----
diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
index fec0fefd08ec0..0a6cc0edbdcc2 100644
--- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
+++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
@@ -37,16 +37,19 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
private $context;
private $rootNodeName = 'response';
private $loadOptions;
+ private $ignoredNodeTypes;
/**
* Construct new XmlEncoder and allow to change the root node element name.
*
- * @param int|null $loadOptions A bit field of LIBXML_* constants
+ * @param int|null $loadOptions A bit field of LIBXML_* constants
+ * @param int[] $ignoredNodeTypes an array of ignored XML node types, each one of the DOM Predefined XML_* Constants
*/
- public function __construct(string $rootNodeName = 'response', int $loadOptions = null)
+ public function __construct(string $rootNodeName = 'response', int $loadOptions = null, array $ignoredNodeTypes = array(XML_PI_NODE, XML_COMMENT_NODE))
{
$this->rootNodeName = $rootNodeName;
$this->loadOptions = null !== $loadOptions ? $loadOptions : LIBXML_NONET | LIBXML_NOBLANKS;
+ $this->ignoredNodeTypes = $ignoredNodeTypes;
}
/**
@@ -105,7 +108,7 @@ public function decode($data, $format, array $context = array())
if (XML_DOCUMENT_TYPE_NODE === $child->nodeType) {
throw new NotEncodableValueException('Document types are not allowed.');
}
- if (!$rootNode && XML_PI_NODE !== $child->nodeType) {
+ if (!$rootNode && !\in_array($child->nodeType, $this->ignoredNodeTypes, true)) {
$rootNode = $child;
}
}
@@ -316,7 +319,7 @@ private function parseXmlValue(\DOMNode $node, array $context = array())
$value = array();
foreach ($node->childNodes as $subnode) {
- if (XML_PI_NODE === $subnode->nodeType) {
+ if (\in_array($subnode->nodeType, $this->ignoredNodeTypes, true)) {
continue;
}
diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php
index 17f7b93b4d837..39bb557c3c6c0 100644
--- a/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php
+++ b/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php
@@ -515,6 +515,62 @@ public function testDecodeIgnoreWhiteSpace()
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
}
+ public function testDecodeIgnoreComments()
+ {
+ $source = <<<'XML'
+
+
+
+
+
+ Benjamin
+ Alexandre
+
+
+ Damien
+ Clay
+
+
+XML;
+
+ $expected = array('person' => array(
+ array('firstname' => 'Benjamin', 'lastname' => 'Alexandre'),
+ array('firstname' => 'Damien', 'lastname' => 'Clay'),
+ ));
+
+ $this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
+ }
+
+ public function testDecodePreserveComments()
+ {
+ $source = <<<'XML'
+
+
+
+
+ Benjamin
+ Alexandre
+
+
+ Damien
+ Clay
+
+
+XML;
+
+ $this->encoder = new XmlEncoder('people', null, array(XML_PI_NODE));
+ $serializer = new Serializer(array(new CustomNormalizer()), array('xml' => new XmlEncoder()));
+ $this->encoder->setSerializer($serializer);
+
+ $expected = array('person' => array(
+ array('firstname' => 'Benjamin', 'lastname' => 'Alexandre', '#comment' => ' This comment should be decoded. '),
+ array('firstname' => 'Damien', 'lastname' => 'Clay'),
+ ));
+
+ $this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
+ }
+
public function testDecodeAlwaysAsCollection()
{
$this->encoder = new XmlEncoder('response', null);