From 74773483143ef06b7e32642ac34c18fe3e270d79 Mon Sep 17 00:00:00 2001 From: Maximilian Ruta Date: Tue, 6 May 2025 11:12:41 +0200 Subject: [PATCH] [Serializer] Add CDATA_WRAPPING_NAME_PATTERN support to XmlEncoder --- .../Component/Serializer/Encoder/XmlEncoder.php | 13 ++++++++++--- .../Serializer/Tests/Encoder/XmlEncoderTest.php | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php index ed66fa30898df..07eb4c5ba6d62 100644 --- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php @@ -59,6 +59,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa public const TYPE_CAST_ATTRIBUTES = 'xml_type_cast_attributes'; public const VERSION = 'xml_version'; public const CDATA_WRAPPING = 'cdata_wrapping'; + public const CDATA_WRAPPING_NAME_PATTERN = 'cdata_wrapping_name_pattern'; public const CDATA_WRAPPING_PATTERN = 'cdata_wrapping_pattern'; public const IGNORE_EMPTY_ATTRIBUTES = 'ignore_empty_attributes'; @@ -72,6 +73,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa self::ROOT_NODE_NAME => 'response', self::TYPE_CAST_ATTRIBUTES => true, self::CDATA_WRAPPING => true, + self::CDATA_WRAPPING_NAME_PATTERN => false, self::CDATA_WRAPPING_PATTERN => '/[<>&]/', self::IGNORE_EMPTY_ATTRIBUTES => false, ]; @@ -440,10 +442,15 @@ private function appendNode(\DOMNode $parentNode, mixed $data, string $format, a /** * Checks if a value contains any characters which would require CDATA wrapping. + * + * @param array $context */ - private function needsCdataWrapping(string $val, array $context): bool + private function needsCdataWrapping(string $name, string $val, array $context): bool { - return ($context[self::CDATA_WRAPPING] ?? $this->defaultContext[self::CDATA_WRAPPING]) && preg_match($context[self::CDATA_WRAPPING_PATTERN] ?? $this->defaultContext[self::CDATA_WRAPPING_PATTERN], $val); + return ($context[self::CDATA_WRAPPING] ?? $this->defaultContext[self::CDATA_WRAPPING]) && + (preg_match($context[self::CDATA_WRAPPING_PATTERN] ?? $this->defaultContext[self::CDATA_WRAPPING_PATTERN], $val) || + (($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)) + ); } /** @@ -471,7 +478,7 @@ private function selectNodeType(\DOMNode $node, mixed $val, string $format, arra return $this->selectNodeType($node, $this->serializer->normalize($val, $format, $context), $format, $context); } elseif (is_numeric($val)) { return $this->appendText($node, (string) $val); - } elseif (\is_string($val) && $this->needsCdataWrapping($val, $context)) { + } elseif (\is_string($val) && $this->needsCdataWrapping($node->nodeName, $val, $context)) { return $this->appendCData($node, $val); } elseif (\is_string($val)) { return $this->appendText($node, $val); diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php index 78699983f7592..82d23320d7cec 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php @@ -568,6 +568,23 @@ public function testDecodeXMLWithProcessInstruction() $this->assertEquals(get_object_vars($obj), $this->encoder->decode($source, 'xml')); } + public function testCDataNamePattern() + { + $expected = <<<'XML' + + + +XML; + $source = ['person' => [ + ['firstname' => 'Benjamin', 'lastname' => 'Alexandre', 'other' => 'data'], + ['firstname' => 'Damien', 'lastname' => 'Clay', 'other' => 'data'], + ]]; + + $this->assertEquals($expected, $this->encoder->encode($source, 'xml',[ + XmlEncoder::CDATA_WRAPPING_NAME_PATTERN => '(firstname|lastname|)' + ])); + } + public function testDecodeIgnoreWhiteSpace() { $source = <<<'XML' 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