From c4f363c2028c4361849ff6b37a76526220da4378 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 7610361d4eb81..4c03057aca85d 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..7c4364d891e58 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' + +datadata + +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