Итак, у меня есть этот образец XML:
<a>
<bb>
<b><c>bc1</c></b>
<b><c>bc2</c></b>
<b><c>bc3</c></b>
</bb>
<cc>
<bb>
<b><c>cbc1</c></b>
<b><c>cbc2</c></b>
<b><c>cbc3</c></b>
</bb>
</cc>
</a>
И это две сущности. Материнская организация:
<?php
final class A
{
/**
* @JMS\Type("array<B>")
* @JMS\XmlList(entry = "b")
* @JMS\SerializedName("bb")
*/
private $bb;
/**
* @JMS\Type("array<B>")
* @JMS\XmlList(entry = "b")
* @JMS\SerializedName("cc/bb")
*/
private $cc;
}
и дочерний объект:
final class B {
/**
* @var string
*
* @ORM\Column(type = "string", length=24)
* @JMS\Type("string")
* @JMS\SerializedName("c")
*/
private $c;
}
Проблема в том, что после десериализации моего xml
$object = $this->serializer->deserialize($xml, A::class, 'xml');
Я получил свойство BB гидратировано, как я ожидал, но свойство cc пусто.
Вопрос в том, есть ли способ заполнить это поле без промежуточного класса / объекта?






Да, это можно сделать аналогично https://stackoverflow.com/a/51766169/2034213, изменив проанализированные данные XML перед началом десериализации. Здесь вы должны использовать прослушиватель pre_deserialize, чтобы переместить cc/bb, чтобы он стал прямым потомком a, с именем, например, ccbb и измените аннотацию $a на @JMS\SerializedName("ccbb")
Однако есть одно болезненное отличие от другого вопроса, связанного выше: при добавлении простого элемента с текстовым содержимым с SimpleXML легко перемещаться по поддереву элементов можно сделать только рекурсивно воссоздавая элементы, один за другим.