Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1cdbb7d

Browse files
committed
feature #23122 Xml encoder optional type cast (ragboyjr)
This PR was submitted for the 2.7 branch but it was merged into the 3.4 branch instead (closes #23122). Discussion ---------- Xml encoder optional type cast | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #22478 | License | MIT | Doc PR | n/a This fixes the issue where certain XML attributes are typecasted when you don't want them to by providing the ability opt out of any typecasting of xml attributes via an option in the context. If this is approved, then I'll add docs in the serializer component describing the new context option. Commits ------- 8f6e67d XML Encoder Optional Type Cast
2 parents 6727a26 + 8f6e67d commit 1cdbb7d

File tree

3 files changed

+48
-9
lines changed

3 files changed

+48
-9
lines changed

src/Symfony/Component/Serializer/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ CHANGELOG
3939
* [DEPRECATION] the `Exception` interface has been renamed to `ExceptionInterface`
4040
* added `ObjectNormalizer` leveraging the `PropertyAccess` component to normalize
4141
objects containing both properties and getters / setters / issers / hassers methods.
42+
* added `xml_type_cast_attributes` context option for allowing users to opt-out of typecasting
43+
xml attributes.
4244

4345
2.6.0
4446
-----

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

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,10 @@ public function decode($data, $format, array $context = array())
119119
unset($data['@xmlns:xml']);
120120

121121
if (empty($data)) {
122-
return $this->parseXml($rootNode);
122+
return $this->parseXml($rootNode, $context);
123123
}
124124

125-
return array_merge($data, (array) $this->parseXml($rootNode));
125+
return array_merge($data, (array) $this->parseXml($rootNode, $context));
126126
}
127127

128128
if (!$rootNode->hasAttributes()) {
@@ -261,11 +261,11 @@ final protected function isElementNameValid($name)
261261
*
262262
* @return array|string
263263
*/
264-
private function parseXml(\DOMNode $node)
264+
private function parseXml(\DOMNode $node, array $context = array())
265265
{
266-
$data = $this->parseXmlAttributes($node);
266+
$data = $this->parseXmlAttributes($node, $context);
267267

268-
$value = $this->parseXmlValue($node);
268+
$value = $this->parseXmlValue($node, $context);
269269

270270
if (!count($data)) {
271271
return $value;
@@ -297,16 +297,17 @@ private function parseXml(\DOMNode $node)
297297
*
298298
* @return array
299299
*/
300-
private function parseXmlAttributes(\DOMNode $node)
300+
private function parseXmlAttributes(\DOMNode $node, array $context = array())
301301
{
302302
if (!$node->hasAttributes()) {
303303
return array();
304304
}
305305

306306
$data = array();
307+
$typeCastAttributes = $this->resolveXmlTypeCastAttributes($context);
307308

308309
foreach ($node->attributes as $attr) {
309-
if (!is_numeric($attr->nodeValue)) {
310+
if (!is_numeric($attr->nodeValue) || !$typeCastAttributes) {
310311
$data['@'.$attr->nodeName] = $attr->nodeValue;
311312

312313
continue;
@@ -331,7 +332,7 @@ private function parseXmlAttributes(\DOMNode $node)
331332
*
332333
* @return array|string
333334
*/
334-
private function parseXmlValue(\DOMNode $node)
335+
private function parseXmlValue(\DOMNode $node, array $context = array())
335336
{
336337
if (!$node->hasChildNodes()) {
337338
return $node->nodeValue;
@@ -348,7 +349,7 @@ private function parseXmlValue(\DOMNode $node)
348349
continue;
349350
}
350351

351-
$val = $this->parseXml($subnode);
352+
$val = $this->parseXml($subnode, $context);
352353

353354
if ('item' === $subnode->nodeName && isset($val['@key'])) {
354355
if (isset($val['#'])) {
@@ -527,6 +528,20 @@ private function resolveXmlRootName(array $context = array())
527528
: $this->rootNodeName;
528529
}
529530

531+
/**
532+
* Get XML option for type casting attributes Defaults to true.
533+
*
534+
* @param array $context
535+
*
536+
* @return bool
537+
*/
538+
private function resolveXmlTypeCastAttributes(array $context = array())
539+
{
540+
return isset($context['xml_type_cast_attributes'])
541+
? (bool) $context['xml_type_cast_attributes']
542+
: true;
543+
}
544+
530545
/**
531546
* Create a DOM document, taking serializer options into account.
532547
*

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,28 @@ public function testDecodeNegativeFloatAttribute()
284284
$this->assertSame(array('@index' => -12.11, '#' => 'Name'), $this->encoder->decode($source, 'xml'));
285285
}
286286

287+
public function testNoTypeCastAttribute()
288+
{
289+
$source = <<<XML
290+
<?xml version="1.0"?>
291+
<document a="018" b="-12.11">
292+
<node a="018" b="-12.11"/>
293+
</document>
294+
XML;
295+
296+
$data = $this->encoder->decode($source, 'xml', array('xml_type_cast_attributes' => false));
297+
$expected = array(
298+
'@a' => '018',
299+
'@b' => '-12.11',
300+
'node' => array(
301+
'@a' => '018',
302+
'@b' => '-12.11',
303+
'#' => '',
304+
),
305+
);
306+
$this->assertSame($expected, $data);
307+
}
308+
287309
public function testEncode()
288310
{
289311
$source = $this->getXmlSource();

0 commit comments

Comments
 (0)