Skip to content

Commit 049982d

Browse files
AndoniLarznicolas-grekas
authored andcommitted
[Serializer] Add XmlEncoder::CDATA_WRAPPING context option
1 parent c868be4 commit 049982d

File tree

5 files changed

+43
-10
lines changed

5 files changed

+43
-10
lines changed

src/Symfony/Component/Serializer/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
* Allow the `Groups` attribute/annotation on classes
1111
* JsonDecode: Add `json_decode_detailed_errors` option
1212
* Make `ProblemNormalizer` give details about Messenger's `ValidationFailedException`
13+
* Add `XmlEncoder::CDATA_WRAPPING` context option
1314

1415
6.3
1516
---

src/Symfony/Component/Serializer/Context/Encoder/XmlEncoderContextBuilder.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,12 @@ public function withVersion(?string $version): static
144144
{
145145
return $this->with(XmlEncoder::VERSION, $version);
146146
}
147+
148+
/**
149+
* Configures whether to wrap strings within CDATA sections.
150+
*/
151+
public function withCdataWrapping(?bool $cdataWrapping): static
152+
{
153+
return $this->with(XmlEncoder::CDATA_WRAPPING, $cdataWrapping);
154+
}
147155
}

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
5858
public const STANDALONE = 'xml_standalone';
5959
public const TYPE_CAST_ATTRIBUTES = 'xml_type_cast_attributes';
6060
public const VERSION = 'xml_version';
61+
public const CDATA_WRAPPING = 'cdata_wrapping';
6162

6263
private array $defaultContext = [
6364
self::AS_COLLECTION => false,
@@ -68,6 +69,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
6869
self::REMOVE_EMPTY_TAGS => false,
6970
self::ROOT_NODE_NAME => 'response',
7071
self::TYPE_CAST_ATTRIBUTES => true,
72+
self::CDATA_WRAPPING => true,
7173
];
7274

7375
public function __construct(array $defaultContext = [])
@@ -424,9 +426,9 @@ private function appendNode(\DOMNode $parentNode, mixed $data, string $format, a
424426
/**
425427
* Checks if a value contains any characters which would require CDATA wrapping.
426428
*/
427-
private function needsCdataWrapping(string $val): bool
429+
private function needsCdataWrapping(string $val, array $context): bool
428430
{
429-
return preg_match('/[<>&]/', $val);
431+
return ($context[self::CDATA_WRAPPING] ?? $this->defaultContext[self::CDATA_WRAPPING]) && preg_match('/[<>&]/', $val);
430432
}
431433

432434
/**
@@ -454,7 +456,7 @@ private function selectNodeType(\DOMNode $node, mixed $val, string $format, arra
454456
return $this->selectNodeType($node, $this->serializer->normalize($val, $format, $context), $format, $context);
455457
} elseif (is_numeric($val)) {
456458
return $this->appendText($node, (string) $val);
457-
} elseif (\is_string($val) && $this->needsCdataWrapping($val)) {
459+
} elseif (\is_string($val) && $this->needsCdataWrapping($val, $context)) {
458460
return $this->appendCData($node, $val);
459461
} elseif (\is_string($val)) {
460462
return $this->appendText($node, $val);

src/Symfony/Component/Serializer/Tests/Context/Encoder/XmlEncoderContextBuilderTest.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ protected function setUp(): void
2929

3030
/**
3131
* @dataProvider withersDataProvider
32-
*
33-
* @param array<string, mixed> $values
3432
*/
3533
public function testWithers(array $values)
3634
{
@@ -47,14 +45,12 @@ public function testWithers(array $values)
4745
->withStandalone($values[XmlEncoder::STANDALONE])
4846
->withTypeCastAttributes($values[XmlEncoder::TYPE_CAST_ATTRIBUTES])
4947
->withVersion($values[XmlEncoder::VERSION])
48+
->withCdataWrapping($values[XmlEncoder::CDATA_WRAPPING])
5049
->toArray();
5150

5251
$this->assertSame($values, $context);
5352
}
5453

55-
/**
56-
* @return iterable<array{0: array<string, mixed>|}>
57-
*/
5854
public static function withersDataProvider(): iterable
5955
{
6056
yield 'With values' => [[
@@ -70,6 +66,7 @@ public static function withersDataProvider(): iterable
7066
XmlEncoder::STANDALONE => false,
7167
XmlEncoder::TYPE_CAST_ATTRIBUTES => true,
7268
XmlEncoder::VERSION => '1.0',
69+
XmlEncoder::CDATA_WRAPPING => false,
7370
]];
7471

7572
yield 'With null values' => [[
@@ -85,6 +82,7 @@ public static function withersDataProvider(): iterable
8582
XmlEncoder::STANDALONE => null,
8683
XmlEncoder::TYPE_CAST_ATTRIBUTES => null,
8784
XmlEncoder::VERSION => null,
85+
XmlEncoder::CDATA_WRAPPING => null,
8886
]];
8987
}
9088
}

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,15 +234,39 @@ public function testEncodeRootAttributes()
234234
public function testEncodeCdataWrapping()
235235
{
236236
$array = [
237-
'firstname' => 'Paul <or Me>',
237+
'firstname' => 'Paul & Martha <or Me>',
238238
];
239239

240240
$expected = '<?xml version="1.0"?>'."\n".
241-
'<response><firstname><![CDATA[Paul <or Me>]]></firstname></response>'."\n";
241+
'<response><firstname><![CDATA[Paul & Martha <or Me>]]></firstname></response>'."\n";
242242

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

246+
public function testEnableCdataWrapping()
247+
{
248+
$array = [
249+
'firstname' => 'Paul & Martha <or Me>',
250+
];
251+
252+
$expected = '<?xml version="1.0"?>'."\n".
253+
'<response><firstname><![CDATA[Paul & Martha <or Me>]]></firstname></response>'."\n";
254+
255+
$this->assertEquals($expected, $this->encoder->encode($array, 'xml', ['cdata_wrapping' => true]));
256+
}
257+
258+
public function testDisableCdataWrapping()
259+
{
260+
$array = [
261+
'firstname' => 'Paul & Martha <or Me>',
262+
];
263+
264+
$expected = '<?xml version="1.0"?>'."\n".
265+
'<response><firstname>Paul &amp; Martha &lt;or Me&gt;</firstname></response>'."\n";
266+
267+
$this->assertEquals($expected, $this->encoder->encode($array, 'xml', ['cdata_wrapping' => false]));
268+
}
269+
246270
public function testEncodeScalarWithAttribute()
247271
{
248272
$array = [

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy