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

我有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时,它的效果很好。


湖上湖
浏览 168回答 3
3回答

largeQ

下面是一个最小的工作例如反序列化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{&nbsp; &nbsp; // ... just as in the question ...}/**&nbsp;* Minimal implementation of POS_Source for purposes of this deserialization example.&nbsp;*/class POS_Source{&nbsp; &nbsp; private $RequestorID;&nbsp; &nbsp; public function setPOS(POS $POS)&nbsp; &nbsp; {&nbsp; &nbsp; }&nbsp; &nbsp; public function getRequestorID()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->RequestorID;&nbsp; &nbsp; }&nbsp; &nbsp; public function setRequestorID($RequestorID)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->RequestorID = $RequestorID;&nbsp; &nbsp; }}$data = '<POS>&nbsp; &nbsp; <!-- ... the same XML as in the question ... --></POS>';$normalizers = [&nbsp; &nbsp; new ArrayDenormalizer(),&nbsp; &nbsp; 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&nbsp; -Source: Doctrine\Common\Collections\ArrayCollection {#11&nbsp; &nbsp; -elements: array:4 [&nbsp; &nbsp; &nbsp; 0 => POS_Source {#17&nbsp; &nbsp; &nbsp; &nbsp; -RequestorID: array:3 [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@Type" => 11&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@ID" => "T921"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "CompanyName" => array:3 [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@Code" => "CP"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@CodeContext" => "123T"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "#" => ""&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; 1 => POS_Source {#27&nbsp; &nbsp; &nbsp; &nbsp; -RequestorID: array:3 [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@Type" => 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@ID" => 34778&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "#" => ""&nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; 2 => POS_Source {#22&nbsp; &nbsp; &nbsp; &nbsp; -RequestorID: array:3 [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@Type" => 9&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@ID" => "ZF"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "#" => ""&nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; 3 => POS_Source {#25&nbsp; &nbsp; &nbsp; &nbsp; -RequestorID: array:3 [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@Type" => 17&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "@ID" => "mabaan"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "#" => ""&nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; ]&nbsp; }}

POPMUISE

这是部分答案,而不是解决方案。因此,看起来反序列化不支持嵌入式php对象,并且您已经创建了一个自定义反序列化方法。我仍在使用解决方案,但简短的答案是您必须遍历标准化数组,然后尝试匹配属性名称。我正在尝试寻找一种方法来查询对象,以仅查询序列化组文档块批注中包含的那些属性。

宝慕林4294392

在反序列化包含其他对象的对象时,必须提供ObjectNormalizer一个类型提取器来确定嵌套对象的类型。use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;// ...$normalizers = [&nbsp; new DateTimeNormalizer(),&nbsp; new ArrayDenormalizer(),&nbsp; new PropertyNormalizer(),&nbsp; new ObjectNormalizer($classMetadataFactory, $metadataAwareNameConverter, null, new ReflectionExtractor()), // added type extractor as fourth argument];
打开App,查看更多内容
随时随地看视频慕课网APP