So I have this sample 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>
And this two entities. Parent entity:
<?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;
}
and child entity:
final class B {
/**
* @var string
*
* @ORM\Column(type="string", length=24)
* @JMS\Type("string")
* @JMS\SerializedName("c")
*/
private $c;
}
Problem is that after deserialization of my xml
$object = $this->serializer->deserialize($xml, A::class, 'xml');
i got property bb hydrated as i expect, but property cc is empty.
Question is if there is any way to fill that field without intermediary class/entity?
Yes, it could be done in a way similar to https://stackoverflow.com/a/51766169/2034213, by modifying the parsed XML data before deserialization starts. Here you would use a pre_deserialize
listener to move cc/bb
to become direct descendant of a
, named e.g. ccbb
, and change the annotation of $a
to @JMS\SerializedName("ccbb")
There is, however, one painful difference to the other question linked above: while adding a simple element with text content is easy with SimpleXML, moving around a subtree of elements can only be done by re-creating the elements recursively, one by one.