我正在尝试反序列化这个非常简单的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>
无论我尝试什么,我都无法将arguments元素反序列化为array
或ArrayCollection
或任何类型的集合,因为数组最终总是空的。
/**
* @Type("array<Model'Argument>")
*/
private $arguments;
/**
* @Type("ArrayCollection<Model'Argument>")
*/
private $arguments;
两者都以空数组结束。所以我尝试为参数创建一个单独的对象
因此,原始属性最终成为
/**
* @Type("Model'Arguments")
*/
private $arguments;
和类
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;
}
}
数组仍然为空。但是,当我将类型更改为@Type("App'Blueprint'Model'Argument")
时,我会得到正确的对象,尽管只是第一个。
当我尝试注册反序列化处理程序时,我无法修改它,因为它是SimpleXmlElement
,然后我将收到It is not yet possible to assign complex types to properties
警告。。。
编辑
目前,我设法用一种愚蠢的方式解决了这个问题:
$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;
}
);
如果有人有更好的解决方案,请将其保留在此处。
你非常接近。您必须定义两个独立的类。
/**
* @Type("Model'Arguments")
*/
public $arguments;
/**
* @Type("array<Model'Argument>")
* @XmlList(inline = true, entry = "argument")
*/
public $argument;
请注意Argument
类中的@XmlList
属性。你也可以移除getter和setter!
为我工作,但不确定这是怎么回事:
我的XML:
<activityData>
<count>1</count>
<facts>
<fact>
<dateTime year="2016" month="11" day="14" hour="0" minute="0" second="0" />
<channel>Administrator</channel>
<count>1</count>
</fact>
</facts>
</activityData>
所以我的模型:
1.
class ActivityData
{
/**
* @var ArrayCollection|ActivityDataFact[]
*
* @Serializer'Type("ArrayCollection<AppBundle'Model'ActivityDataFact>")
* @Serializer'XmlList(entry="fact")
*/
private $facts;
...
}
2.
class ActivityDataFact
{
/**
* @var DateTime
*
* @Serializer'Type("AppBundle'Model'DateTime")
* @Serializer'SerializedName("dateTime")
*/
private $date;
/**
* @var string
*
* @Serializer'Type("string")
*/
private $channel;
/**
* @var integer
*
* @Serializer'Type("integer")
*/
private $count;
...
}
3.
class DateTime
{
/**
* @var string
*
* @Serializer'Type("integer")
* @Serializer'XmlAttribute()
*/
private $year = 1970;
/**
* @var string
*
* @Serializer'Type("integer")
* @Serializer'XmlAttribute()
*/
private $month = 1;
/**
* @var string
*
* @Serializer'Type("integer")
* @Serializer'XmlAttribute()
*/
private $day = 1;
/**
* @var string
*
* @Serializer'Type("integer")
* @Serializer'XmlAttribute()
*/
private $hour = 0;
/**
* @var string
*
* @Serializer'Type("integer")
* @Serializer'XmlAttribute()
*/
private $minute = 0;
/**
* @var string
*
* @Serializer'Type("integer")
* @Serializer'XmlAttribute()
*/
private $second = 0;
...
}