diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
index ed66fa30898df..cc983042fefb4 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 ARRAY_AS_ITEM = 'array_as_item';
public const CDATA_WRAPPING_PATTERN = 'cdata_wrapping_pattern';
public const IGNORE_EMPTY_ATTRIBUTES = 'ignore_empty_attributes';
@@ -71,6 +72,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
self::REMOVE_EMPTY_TAGS => false,
self::ROOT_NODE_NAME => 'response',
self::TYPE_CAST_ATTRIBUTES => true,
+ self::ARRAY_AS_ITEM => false,
self::CDATA_WRAPPING => true,
self::CDATA_WRAPPING_PATTERN => '/[<>&]/',
self::IGNORE_EMPTY_ATTRIBUTES => false,
@@ -345,6 +347,7 @@ private function buildXml(\DOMNode $parentNode, mixed $data, string $format, arr
{
$append = true;
$removeEmptyTags = $context[self::REMOVE_EMPTY_TAGS] ?? $this->defaultContext[self::REMOVE_EMPTY_TAGS] ?? false;
+ $arrayAsItem = $context[self::ARRAY_AS_ITEM] ?? $this->defaultContext[self::ARRAY_AS_ITEM] ?? false;
$encoderIgnoredNodeTypes = $context[self::ENCODER_IGNORED_NODE_TYPES] ?? $this->defaultContext[self::ENCODER_IGNORED_NODE_TYPES];
if (\is_array($data) || ($data instanceof \Traversable && (null === $this->serializer || !$this->serializer->supportsNormalization($data, $format)))) {
@@ -373,7 +376,7 @@ private function buildXml(\DOMNode $parentNode, mixed $data, string $format, arr
}
} elseif (\is_array($data) && false === is_numeric($key)) {
// Is this array fully numeric keys?
- if (ctype_digit(implode('', array_keys($data)))) {
+ if (!$arrayAsItem && ctype_digit(implode('', array_keys($data)))) {
/*
* Create nodes to append to $parentNode based on the $key of this array
* Produces - 0
- 1
diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php
index 78699983f7592..5c218d541dd24 100644
--- a/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php
+++ b/src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php
@@ -1017,4 +1017,48 @@ public function testEncodeIgnoringEmptyAttribute()
$this->assertEquals($expected, $this->encoder->encode($data, 'xml', ['ignore_empty_attributes' => true]));
}
+
+ public function testEncodeArrayAsItem()
+ {
+ $expected = <<<'XML'
+
+- BenjaminAlexandre
- DamienClay
+
+XML;
+ $source = ['person' => [
+ ['firstname' => 'Benjamin', 'lastname' => 'Alexandre'],
+ ['firstname' => 'Damien', 'lastname' => 'Clay'],
+ ]];
+
+ $this->assertEquals($expected, $this->encoder->encode($source, 'xml', [
+ XmlEncoder::ARRAY_AS_ITEM => true,
+ ]));
+ }
+
+ public function testDecodeArrayAsItem()
+ {
+ $source = <<<'XML'
+
+
+
+ -
+ Benjamin
+ Alexandre
+
+ -
+ Damien
+ Clay
+
+
+
+XML;
+ $expected = ['person' => [
+ ['firstname' => 'Benjamin', 'lastname' => 'Alexandre', '@key' => 0],
+ ['firstname' => 'Damien', 'lastname' => 'Clay', '@key' => 1],
+ ]];
+
+ $this->assertEquals($expected, $this->encoder->decode($source, 'xml', [
+ XmlEncoder::ARRAY_AS_ITEM => true,
+ ]));
+ }
}