I am trying to deserialize this very simple XML:
<?xml version="1.0" encoding="utf-8"?>
<root>
<namespace>foo</namespace>
<resource>bar</resource>
<description>baz</description>
<arguments>
<argument>
<name>foo</name>
<type>string</type>
<description>foo</description>
</argument>
<argument>
<name>bar</name>
<type>string</type>
<description>bar</description>
</argument>
</arguments>
</root>
No matter what I try I can not deserialize arguments element into array
or ArrayCollection
or any kind of collection as the array always ends up empty.
/**
* @Type("array<Model\Argument>")
*/
private $arguments;
/**
* @Type("ArrayCollection<Model\Argument>")
*/
private $arguments;
Both end up as empty array. So I tried creating a separate object for arguments
Thus the original property ends up as
/**
* @Type("Model\Arguments")
*/
private $arguments;
and the class
class Arguments {
/**
* @Type("array<App\Blueprint\Model\Argument>")
*/
private $arguments;
/**
* @return mixed
*/
public function getArguments() {
return $this->arguments;
}
/**
* @param mixed $arguments
*/
public function setArguments($arguments) {
$this->arguments = $arguments;
}
}
the array is still empty. But, when I change the type to @Type("App\Blueprint\Model\Argument")
I will get the correct object, though only the first one.
When I try to register a deserialization handler I am unable to modify it because it comes as SimpleXmlElement
and then I will get It is not yet possible to assign complex types to properties
warning...
EDIT
For now I managed to solve it in a stupid way:
$registry->registerHandler(
'deserialization',
'Model\Arguments',
'xml',
function(XmlDeserializationVisitor $visitor, $data, array $type, DeserializationContext $context) {
$arguments = [];
foreach($data->children() as $child) {
$arguments[] = SerializerBuilder::create()
->build()
->deserialize($child->asXML(), 'Model\Argument', 'xml');
}
return $arguments;
}
);
Just leaving it out here if someone has a better solution.
You were quite close. You have to define two separate classes.
/**
* @Type("Model\Arguments")
*/
public $arguments;
/**
* @Type("array<Model\Argument>")
* @XmlList(inline = true, entry = "argument")
*/
public $argument;
Note the @XmlList
property in the Argument
class. You can remove the getter and setter too!