为了账号安全,请及时绑定邮箱和手机立即绑定

如何在XML Symfony中将XML反序列化为包含数组集合的对象

如何在XML Symfony中将XML反序列化为包含数组集合的对象

PHP
湖上湖 2021-04-25 10:17:58
我有XML格式<POS>    <Source PseudoCCode="BOA" ISOCountry="US" AgentDutyCode="J114N">        <RequestorID Type="11" ID="T921">            <CompanyName Code="CP" CodeContext="123T"/>        </RequestorID>    </Source>    <Source>        <RequestorID Type="1" ID="34778"/>      </Source>    <Source>        <RequestorID Type="9" ID="ZF"/>    </Source>    <Source>        <RequestorID Type="17" ID="mabaan"/>    </Source></POS>`我有一个要反序列化的php对象。  class POS  { /**   * @ORM\OneToMany(targetEntity="POS_Source", mappedBy="POS", orphanRemoval=true) * @Groups("Include") */private $Source;public function __construct(){     $this->Source = new ArrayCollection();}/** * @return ArrayCollection|OTA_POS_Source[] */public function getSource(): ArrayCollection{    return $this->Source;}public function addSource(POS_Source $source): self{    if (!$this->Source->contains($source)) {        $this->Source[] = $source;        $source->setPOS($this);    }    return $this;}public function removeSource(POS_Source $source): self{    if ($this->Source->contains($source)) {        $this->Source->removeElement($source);        // set the owning side to null (unless already changed)        if ($source->getPOS() === $this) {            $source->setPOS(null);        }    }    return $this;}它给了我POS对象,而不是给它一个下面的数组,而不是POS_Source对象的集合。 POS {#839 ▼   -id: null   -Source: array:5 [▼     0 => array:4 [▶]     1 => array:1 [▶]     2 => array:1 [▶]     3 => array:1 [▶]     4 => array:1 [▶]   ] }我如何才能使这项工作一直填充到对象树的底部。当我从对象结构序列化为XML时,它的效果很好。
查看完整描述

3 回答

?
largeQ

TA贡献2039条经验 获得超7个赞

下面是一个最小的工作例如反序列化XML到单个POS实例与ArrayCollection的POS_Source实例。我扔掉了对反序列化此特定XML而言不是必不可少的所有规范化器等。


use Doctrine\Common\Collections\ArrayCollection;

use Symfony\Component\Serializer\Encoder\XmlEncoder;

use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;

use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

use Symfony\Component\Serializer\Serializer;

use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;


class POS

{

    // ... just as in the question ...

}


/**

 * Minimal implementation of POS_Source for purposes of this deserialization example.

 */

class POS_Source

{

    private $RequestorID;


    public function setPOS(POS $POS)

    {

    }


    public function getRequestorID()

    {

        return $this->RequestorID;

    }


    public function setRequestorID($RequestorID)

    {

        $this->RequestorID = $RequestorID;

    }

}


$data = '<POS>

    <!-- ... the same XML as in the question ... -->

</POS>';


$normalizers = [

    new ArrayDenormalizer(),

    new ObjectNormalizer(null, null, null, new ReflectionExtractor())

];

$encoders = [new XmlEncoder()];


$serializer = new Serializer($normalizers, $encoders);


$pos = $serializer->deserialize($data,POS::class,'xml');

dump($pos);

印刷:


POS {#14

  -Source: Doctrine\Common\Collections\ArrayCollection {#11

    -elements: array:4 [

      0 => POS_Source {#17

        -RequestorID: array:3 [

          "@Type" => 11

          "@ID" => "T921"

          "CompanyName" => array:3 [

            "@Code" => "CP"

            "@CodeContext" => "123T"

            "#" => ""

          ]

        ]

      }

      1 => POS_Source {#27

        -RequestorID: array:3 [

          "@Type" => 1

          "@ID" => 34778

          "#" => ""

        ]

      }

      2 => POS_Source {#22

        -RequestorID: array:3 [

          "@Type" => 9

          "@ID" => "ZF"

          "#" => ""

        ]

      }

      3 => POS_Source {#25

        -RequestorID: array:3 [

          "@Type" => 17

          "@ID" => "mabaan"

          "#" => ""

        ]

      }

    ]

  }

}


查看完整回答
反对 回复 2021-05-07
?
POPMUISE

TA贡献1765条经验 获得超5个赞

这是部分答案,而不是解决方案。

因此,看起来反序列化不支持嵌入式php对象,并且您已经创建了一个自定义反序列化方法。

我仍在使用解决方案,但简短的答案是您必须遍历标准化数组,然后尝试匹配属性名称。我正在尝试寻找一种方法来查询对象,以仅查询序列化组文档块批注中包含的那些属性。


查看完整回答
反对 回复 2021-05-07
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

在反序列化包含其他对象的对象时,必须提供ObjectNormalizer一个类型提取器来确定嵌套对象的类型。


use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;

// ...

$normalizers = [

  new DateTimeNormalizer(),

  new ArrayDenormalizer(),

  new PropertyNormalizer(),

  new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter, null, new ReflectionExtractor()), // added type extractor as fourth argument

];


查看完整回答
反对 回复 2021-05-07
  • 3 回答
  • 0 关注
  • 167 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信