Skip to content

Commit

Permalink
feature #27926 [Serializer] XmlEncoder doesn't ignore PI nodes while …
Browse files Browse the repository at this point in the history
…encoding (maidmaid)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[Serializer] XmlEncoder doesn't ignore PI nodes while encoding

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | no
| Fixed tickets | /
| License       | MIT
| Doc PR        | /

It's sometimes important to get only the XML body without the processing instructions (like the `<?xml version="1.0" ?>` on the top of your XML doc). At the moment, it's possible to ignore them while decoding, but not while encoding.

```php
$encoder = new XmlEncoder('response', null, $ignoredNodeTypes = [XML_PI_NODE]);
echo $encoder->encode([], 'xml');
```
```
Expected:
<response/>

Actual:
<?xml version="1.0"?>
<response/>
```

So, a new `$encoderIgnoredNodeTypes` arg is added to the constructor which will be:

```php
public function __construct(string $rootNodeName = 'response', int $loadOptions = null, array $decoderIgnoredNodeTypes = array(XML_PI_NODE, XML_COMMENT_NODE), array $encoderIgnoredNodeTypes = array())
```

Commits
-------

2223fcc Allow to ignore PI while encoding
  • Loading branch information
dunglas committed Aug 25, 2018
2 parents 4e4b216 + 2223fcc commit 9ef362e
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
21 changes: 12 additions & 9 deletions src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
Expand Up @@ -38,19 +38,22 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
private $context;
private $rootNodeName = 'response';
private $loadOptions;
private $ignoredNodeTypes;
private $decoderIgnoredNodeTypes;
private $encoderIgnoredNodeTypes;

/**
* Construct new XmlEncoder and allow to change the root node element name.
*
* @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
* @param int|null $loadOptions A bit field of LIBXML_* constants
* @param int[] $decoderIgnoredNodeTypes an array of ignored XML node types while decoding, each one of the DOM Predefined XML_* Constants
* @param int[] $encoderIgnoredNodeTypes an array of ignored XML node types while encoding, each one of the DOM Predefined XML_* Constants
*/
public function __construct(string $rootNodeName = 'response', int $loadOptions = null, array $ignoredNodeTypes = array(XML_PI_NODE, XML_COMMENT_NODE))
public function __construct(string $rootNodeName = 'response', int $loadOptions = null, array $decoderIgnoredNodeTypes = array(XML_PI_NODE, XML_COMMENT_NODE), array $encoderIgnoredNodeTypes = array())
{
$this->rootNodeName = $rootNodeName;
$this->loadOptions = null !== $loadOptions ? $loadOptions : LIBXML_NONET | LIBXML_NOBLANKS;
$this->ignoredNodeTypes = $ignoredNodeTypes;
$this->decoderIgnoredNodeTypes = $decoderIgnoredNodeTypes;
$this->encoderIgnoredNodeTypes = $encoderIgnoredNodeTypes;
}

/**
Expand All @@ -59,7 +62,7 @@ public function __construct(string $rootNodeName = 'response', int $loadOptions
public function encode($data, $format, array $context = array())
{
if ($data instanceof \DOMDocument) {
return $data->saveXML();
return $data->saveXML(\in_array(XML_PI_NODE, $this->encoderIgnoredNodeTypes, true) ? $data->documentElement : null);
}

$xmlRootNodeName = $this->resolveXmlRootName($context);
Expand All @@ -76,7 +79,7 @@ public function encode($data, $format, array $context = array())
$this->appendNode($this->dom, $data, $xmlRootNodeName);
}

return $this->dom->saveXML();
return $this->dom->saveXML(\in_array(XML_PI_NODE, $this->encoderIgnoredNodeTypes, true) ? $this->dom->documentElement : null);
}

/**
Expand Down Expand Up @@ -109,7 +112,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 && !\in_array($child->nodeType, $this->ignoredNodeTypes, true)) {
if (!$rootNode && !\in_array($child->nodeType, $this->decoderIgnoredNodeTypes, true)) {
$rootNode = $child;
}
}
Expand Down Expand Up @@ -327,7 +330,7 @@ private function parseXmlValue(\DOMNode $node, array $context = array())
$value = array();

foreach ($node->childNodes as $subnode) {
if (\in_array($subnode->nodeType, $this->ignoredNodeTypes, true)) {
if (\in_array($subnode->nodeType, $this->decoderIgnoredNodeTypes, true)) {
continue;
}

Expand Down
Expand Up @@ -773,6 +773,15 @@ public function testEncodeComment()
$this->assertEquals($expected, $this->encoder->encode($data, 'xml'));
}

public function testEncodeWithoutPI()
{
$encoder = new XmlEncoder('response', null, array(), array(XML_PI_NODE));

$expected = '<response/>';

$this->assertEquals($expected, $encoder->encode(array(), 'xml'));
}

/**
* @return XmlEncoder
*/
Expand Down

0 comments on commit 9ef362e

Please sign in to comment.