Skip to content

Commit c4f363c

Browse files
author
Maximilian Ruta
committed
[Serializer] Add CDATA_WRAPPING_NAME_PATTERN support to XmlEncoder
1 parent bbd9858 commit c4f363c

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
5959
public const TYPE_CAST_ATTRIBUTES = 'xml_type_cast_attributes';
6060
public const VERSION = 'xml_version';
6161
public const CDATA_WRAPPING = 'cdata_wrapping';
62+
public const CDATA_WRAPPING_NAME_PATTERN = 'cdata_wrapping_name_pattern';
6263
public const CDATA_WRAPPING_PATTERN = 'cdata_wrapping_pattern';
6364
public const IGNORE_EMPTY_ATTRIBUTES = 'ignore_empty_attributes';
6465

@@ -72,6 +73,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
7273
self::ROOT_NODE_NAME => 'response',
7374
self::TYPE_CAST_ATTRIBUTES => true,
7475
self::CDATA_WRAPPING => true,
76+
self::CDATA_WRAPPING_NAME_PATTERN => false,
7577
self::CDATA_WRAPPING_PATTERN => '/[<>&]/',
7678
self::IGNORE_EMPTY_ATTRIBUTES => false,
7779
];
@@ -440,10 +442,15 @@ private function appendNode(\DOMNode $parentNode, mixed $data, string $format, a
440442

441443
/**
442444
* Checks if a value contains any characters which would require CDATA wrapping.
445+
*
446+
* @param array<string, mixed> $context
443447
*/
444-
private function needsCdataWrapping(string $val, array $context): bool
448+
private function needsCdataWrapping(string $name, string $val, array $context): bool
445449
{
446-
return ($context[self::CDATA_WRAPPING] ?? $this->defaultContext[self::CDATA_WRAPPING]) && preg_match($context[self::CDATA_WRAPPING_PATTERN] ?? $this->defaultContext[self::CDATA_WRAPPING_PATTERN], $val);
450+
return ($context[self::CDATA_WRAPPING] ?? $this->defaultContext[self::CDATA_WRAPPING])
451+
&& (preg_match($context[self::CDATA_WRAPPING_PATTERN] ?? $this->defaultContext[self::CDATA_WRAPPING_PATTERN], $val)
452+
|| (($context[self::CDATA_WRAPPING_NAME_PATTERN] ?? $this->defaultContext[self::CDATA_WRAPPING_NAME_PATTERN]) && preg_match($context[self::CDATA_WRAPPING_NAME_PATTERN] ?? $this->defaultContext[self::CDATA_WRAPPING_NAME_PATTERN], $name))
453+
);
447454
}
448455

449456
/**
@@ -471,7 +478,7 @@ private function selectNodeType(\DOMNode $node, mixed $val, string $format, arra
471478
return $this->selectNodeType($node, $this->serializer->normalize($val, $format, $context), $format, $context);
472479
} elseif (is_numeric($val)) {
473480
return $this->appendText($node, (string) $val);
474-
} elseif (\is_string($val) && $this->needsCdataWrapping($val, $context)) {
481+
} elseif (\is_string($val) && $this->needsCdataWrapping($node->nodeName, $val, $context)) {
475482
return $this->appendCData($node, $val);
476483
} elseif (\is_string($val)) {
477484
return $this->appendText($node, $val);

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,23 @@ public function testDecodeXMLWithProcessInstruction()
568568
$this->assertEquals(get_object_vars($obj), $this->encoder->decode($source, 'xml'));
569569
}
570570

571+
public function testCDataNamePattern()
572+
{
573+
$expected = <<<'XML'
574+
<?xml version="1.0"?>
575+
<response><person><firstname><![CDATA[Benjamin]]></firstname><lastname><![CDATA[Alexandre]]></lastname><other>data</other></person><person><firstname><![CDATA[Damien]]></firstname><lastname><![CDATA[Clay]]></lastname><other>data</other></person></response>
576+
577+
XML;
578+
$source = ['person' => [
579+
['firstname' => 'Benjamin', 'lastname' => 'Alexandre', 'other' => 'data'],
580+
['firstname' => 'Damien', 'lastname' => 'Clay', 'other' => 'data'],
581+
]];
582+
583+
$this->assertEquals($expected, $this->encoder->encode($source, 'xml', [
584+
XmlEncoder::CDATA_WRAPPING_NAME_PATTERN => '/(firstname|lastname)/',
585+
]));
586+
}
587+
571588
public function testDecodeIgnoreWhiteSpace()
572589
{
573590
$source = <<<'XML'

0 commit comments

Comments
 (0)