Есть CommerceML файл, который приходит от 1С, в нем указываются товарные группы в виде:
Товарные группы из import.xml
<Группы>
<Группа>
<Ид>58a742d8-dcc4-11ec-9656-fa163ec2d0ed</Ид>
<Наименование>Ковры</Наименование>
<Группы>
<Группа>
<Ид>5df7cfa0-dcc4-11ec-9656-fa163ec2d0ed</Ид>
<Наименование>Merinos</Наименование>
<Группы>
<Группа>
<Ид>6a0d73a8-dcc4-11ec-9656-fa163ec2d0ed</Ид>
<Наименование>Buhara</Наименование>
<Группы>
<Группа>
<Ид>6a0d73a8-dcc4-11ec-9656-fa163ec2d0ez</Ид>
<Наименование>Fourth Level Children</Наименование>
</Группа>
<Группа>
<Ид>648a64cc-dcc4-11ec-9656-fa163ec2d0ex</Ид>
<Наименование>Fourth Level Children</Наименование>
</Группа>
</Группы>
</Группа>
<Группа>
<Ид>648a64cc-dcc4-11ec-9656-fa163ec2d0ed</Ид>
<Наименование>Crystal</Наименование>
</Группа>
</Группы>
</Группа>
<Группа>
<Ид>5df7cfa0-dcc4-11ec-9656-fa163ec2d0zd</Ид>
<Наименование>Другое</Наименование>
</Группа>
</Группы>
</Группа>
</Группы>
Данная структура представляет из себя иерархию, и я хочу получить подобную структуру в виде DTO.
Для этого я создал сам
GroupDto
GroupDto.php
<?php
namespace App\Services\CommerceML\Dto;
use Spatie\DataTransferObject\DataTransferObject;
use Symfony\Component\Serializer\Annotation\SerializedName;
class ≠ extends DataTransferObject
{
/**
* @SerializedName("Ид")
*/
public string $id = '';
/**
* @SerializedName("Наименование")
*/
public string $name = '';
/**
* @SerializedName("Группы")
*/
public array $childrens = [];
}
Важный момент
public array $childrens = [];
в DTO должен представлять из себя массив таких же DTO как и родитель, то есть класс GroupDto.
Собственно, сам сериализатор настроен так:
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$extractor = new PropertyInfoExtractor([], [new PhpDocExtractor(), new ReflectionExtractor()]);
$metadataAwareNameConverter = new MetadataAwareNameConverter($classMetadataFactory);
$encoders = [new XmlEncoder()];
$normalizers = [new ArrayDenormalizer(), new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter, null ,$extractor)];
$serializer = new Serializer($normalizers, $encoders);
И вызов сериализатора:
$xml = simplexml_load_file(storage_path('1cExchange/1/import.xml'));
foreach ($xml->Классификатор->Группы as $group) {
dd($serializer->deserialize($group->Группа->asXML(), GroupDto::class, 'xml', ['flatten_nested_attributes' => true]));
}
Но в таком случае получаю такой вывод:
Вывод^ App\Services\CommerceML\Dto\GroupDto {#628 ▼
#exceptKeys: []
#onlyKeys: []
+id: "58a742d8-dcc4-11ec-9656-fa163ec2d0ed"
+name: "Ковры"
+childrens: array:1 [▼
"Группа" => array:2 [▼
0 => array:3 [▼
"Ид" => "5df7cfa0-dcc4-11ec-9656-fa163ec2d0ed"
"Наименование" => "Merinos"
"Группы" => array:1 [▶]
]
1 => array:2 [▼
"Ид" => "5df7cfa0-dcc4-11ec-9656-fa163ec2d0zd"
"Наименование" => "Pepsi"
]
]
]
}
Хотелось бы, чтобы массив children был содержал в себе таки же GroupDto сформированные, а не чистые массивы, можно ли это как-то сделать вообще?