我有以下XML:
<CinemaListExport>
<Cinema>
....
<screens>
<screen></screen>
<screen></screen>
</screens>
</Cinema>
<Cinema>
....
</Cinema>
<CinemaListExport>
我正在尝试将其转换为以下对象:
class CinemaList
{
/**
* @var Cinema[]
*/
public $cinema;
public function __construct()
{
$this->cinema = new ArrayCollection();
}
public function addCinema(Cinema $cinema)
{
$this->cinema[] = $cinema;
}
class Cinema
{
fields...
/**
* @var Screen[]
*/
public $screens = [];
具有以下代码:
$normalizers = [
new ArrayDenormalizer(),
new ObjectNormalizer(null, null, null, new ReflectionExtractor())
];
$encoders = [new XmlEncoder()];
$serializer = new Serializer($normalizers, $encoders);
$res = $serializer->deserialize($xml, CinemaList::class, 'xml');
无论我做什么,我总是得到以下信息:
class CinemaList#265 (1) {
public $cinema =>
class Doctrine\Common\Collections\ArrayCollection#317 (1) {
private $elements =>
array(0) {
}
}
}
有人能指出我正确的方向吗?我在这里做错了什么? 我只需要CinemaList包含所有影院,每个影院都包含所有屏幕
答案 0 :(得分:1)
好吧,我不得不开发您的解决方案并进行一些搜索,以了解为什么这种简单的用例无法正常工作。
首先,您错过了归一化器ArrayDenormalizer
,需要对电影和屏幕集合进行反序列化:
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
$objectNormalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
$serializer = new Serializer(
[new ArrayDenormalizer(), $objectNormalizer], [new XmlEncoder()]
);
没有这个规范化器数组和集合就被跳过。
关于序列化/反序列化还有另一件事,尤其是使用ObjectNormalizer
组件的PropertyAccess
。
如果要使其工作,则必须同时实现方法adder
和remover
。
PropertyAccessor :: writeProperty方法中发生了很多事情。我不会解释所有的机制,但是很快:如果您有方法addXXX和removeXXX,则将优先使用addXXX。照顾自己 !如果您仅具有addXXX方法,则将不会使用该方法……我不知道他们为什么这样做,但是当然有充分的理由。 第二个选项是二传手。如果存在(并且您没有removeXXX或addXXX),那么它将用于添加集合中的项目。
来自here
我在一个新的symfony项目中进行了一些成功的测试。如果您仍然遇到问题,我们将很乐意为您提供帮助。