Symfony 3.4文档说明了反序列化数组的以下内容:
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Serializer;
$serializer = new Serializer(
array(new GetSetMethodNormalizer(), new ArrayDenormalizer()),
array(new JsonEncoder())
);
$data = ...; // The serialized data from the previous example
$persons = $serializer->deserialize($data, 'Acme\Person[]', 'json');
json字符串如下:
[{ “名称”: “foo” 的, “年龄”:99, “运动员”:假},{ “名称”: “棒”, “年龄”:33, “运动员”:真}]
所以我尝试用我的XML结构做同样的事情。这不是一个真正的结构,因为我正在测试这件事。
XML结构:
<<<EOF
<response>
<book>
<titulo>foo</titulo>
<isbn>99</isbn>
<autor>Autor</autor>
<editor>Editor</editor>
</book>
<book>
<titulo>foo2</titulo>
<isbn>100</isbn>
<autor>Autor2</autor>
<editor>Editor2</editor>
</book>
</response>
EOF;
Response是默认的根节点名称。我有一个Book实体,其字段定义相同。 我试着像这样反序列化:
use AppBundle\Entity\Book;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new GetSetMethodNormalizer(), new ArrayDenormalizer());
$serializer = new Serializer($normalizers, $encoders);
$serializer->deserialize($data, 'AppBundle\Entity\Book[]', 'xml');
当我执行deserialize变量的var_dump时,输出如下:
array(1){[“book”] =&gt; object(AppBundle \ Entity \ Book)#385(11){[“isbn”:protected] =&gt; NULL [“autor”:protected] =&gt; NULL [“titulo”:protected] =&gt; NULL [“fecha_ini”:protected] =&gt; NULL [“fecha_fin”:protected] =&gt; NULL [“editor”:protected] =&gt; NULL [“imgUrl”:protected] =&gt; NULL [“cod_autor”:protected] =&gt; NULL [“cod_editorial”:protected] =&gt; NULL [“cod_coleccion”:protected] =&gt; NULL [“cod_mat”:protected] =&gt; NULL}}
当我期望2个元素时,无法识别数据,并且数组只有一个元素。
有人经历过类似的事吗?你能帮助我在哪里寻找解决方案吗?
提前致谢。
答案 0 :(得分:0)
XML不是JSON,并且根元素也不是“只是数组的包装器”,因此您必须给予应有的重视。有两种方法可以解决此问题:
1。为根元素引入反序列化模型-类似
class Response
{
/**
* @var Book[]
*/
protected $book;
/**
* @return Book[]
*/
public function getBook(): array
{
return $this->book;
}
/**
* @param Book[] $book
*/
public function setBook(array $book): void
{
$this->book = $book;
}
}
然后访问类似
的图书$response = $serializer->deserialize($xml, 'App\Entity\Response', 'xml');
$books = $response->getBook();
但是,在这种情况下,简单的序列化程序配置是不够的-为了使书籍正确地反序列化为Book
实例,有必要向extract type information for the nested entities添加一些功能: / p>
$encoders = array(new XmlEncoder());
$normalizers = array(new GetSetMethodNormalizer(null, null, new PhpDocExtractor()), new ArrayDenormalizer()); // <- PhpDocExtractor
$serializer = new Serializer($normalizers, $encoders);
PhpDocExtractor
从PhpDoc注释中提取类型信息。
2。引入自定义反规范化器
或者,您可以使用自定义的反规范化器直接加入反序列化过程
use App\Entity\Book;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
class BookArrayDenormalizer extends ArrayDenormalizer
{
public function supportsDenormalization($data, $type, $format = null, array $context = [])
{
// only support deserialization of Book[]
return Book::class.'[]' === $type;
}
public function denormalize($data, $class, $format = null, array $context = [])
{
return parent::denormalize(
$data['book'], // this is the magic to ignore the root element
$class, $format, $context
);
}
}
并享受在不使用包装对象的情况下反序列化一系列Book的功能:
$normalizers = array(new GetSetMethodNormalizer(), new BookArrayDenormalizer(), new ArrayDenormalizer()); // add the new denormalizer
$encoders = array(new XmlEncoder());
$serializer = new Serializer($normalizers, $encoders);
$books = $serializer->deserialize($xml, 'App\Entity\Book[]', 'xml');