Сериализация Symfony с дочерними объектами в XML - PullRequest
0 голосов
/ 03 июля 2018

Я пытаюсь сериализовать сущность с дочерними элементами в XML-файл, используя встроенный сериализатор из Symfony. Проблема в том, что сериализатор не отформатировать коллекцию детей в xml так, как я ожидал.

Я запускаю сериализатор следующим образом:

    $normalizer = new ObjectNormalizer();

    $normalizer->setCircularReferenceHandler(function ($object) {
        return $object->getId();
    });

    $this->serializer = new Serializer(
        [
            $normalizer,
            new GetSetMethodNormalizer(),
            new ArrayDenormalizer()
        ],
        [new XmlEncoder(), new JsonEncoder()]
    );

И вызовите сериализатор следующим образом:

    $this->serializer->serialize(
        $entityCollection,
        'xml',
        [
            'xml_format_output' => true,
            'xml_root_node_name' => 'events'
        ]
    );

Что приводит к следующему XML:

 <item key="140">
      <id/>
      <name>Lorum ipsum</name>
      <lastEdited/>
      <url>Lorum ipsum</url>
      <region>Limburg</region>
      <description>Lorum ipsum</description>
      <location/>
      <contact/>
      <content><![CDATA[<p>Lorum ipsum</p>]]></content>
      <priceChild/>
      <priceAdult/>
      <startTime>15:00:00</startTime>
      <endTime>15:45:00</endTime>
      <eventDates/>
      <eventImages>
        <id/>
        <url>herfstvoorstelling.jpg</url>
      </eventImages>
      <eventImages>
        <id/>
        <url>test.jpg</url>
      </eventImages>
    </item>

Как видите, узел <eventImages> представлен дважды там, где я ожидал, что он будет иметь следующую структуру:

      <eventImages>
        <eventImage>
          <id/>
          <url>herfstvoorstelling.jpg</url>
        </eventImage>
        <eventImage>
          <id/>
          <url>test.jpg</url>
        </eventImage>
      </eventImages>

Используемые объекты:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;


/**
 * @ORM\Entity(repositoryClass="App\Repository\EventRepository")
 */
class Event
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $lastEdited;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $url;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $region;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $description;
    /**
     * @ORM\Column(type="string", length=255)
     */
    private $location;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $contact;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $content;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $priceChild;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $priceAdult;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $startTime;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $endTime;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\EventDate", mappedBy="event")
     */
    private $eventDates;

    /**
     * @MaxDepth(2)
     * @ORM\OneToMany(targetEntity="App\Entity\EventImage", mappedBy="event")
     */
    private $eventImages;

    public function __construct()
    {
        $this->eventDates = new ArrayCollection();
        $this->eventImages = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getLastEdited(): ?string
    {
        return $this->lastEdited;
    }

    public function setLastEdited(string $lastEdited): self
    {
        $this->lastEdited = $lastEdited;

        return $this;
    }

    public function getUrl(): ?string
    {
        return $this->url;
    }

    public function setUrl(string $url): self
    {
        $this->url = $url;

        return $this;
    }

    public function getRegion(): ?string
    {
        return $this->region;
    }

    public function setRegion(string $region): self
    {
        $this->region = $region;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(string $description): self
    {
        $this->description = $description;

        return $this;
    }

    public function getLocation(): ?string
    {
        return $this->location;
    }

    public function setLocation(string $location): self
    {
        $this->location = $location;

        return $this;
    }

    public function getContact(): ?string
    {
        return $this->contact;
    }

    public function setContact(string $contact): self
    {
        $this->contact = $contact;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getPriceChild(): ?string
    {
        return $this->priceChild;
    }

    public function setPriceChild(string $priceChild): self
    {
        $this->priceChild = $priceChild;

        return $this;
    }

    public function getPriceAdult(): ?string
    {
        return $this->priceAdult;
    }

    public function setPriceAdult(string $priceAdult): self
    {
        $this->priceAdult = $priceAdult;

        return $this;
    }

    public function getStartTime(): ?string
    {
        return $this->startTime;
    }

    public function setStartTime(string $startTime): self
    {
        $this->startTime = $startTime;

        return $this;
    }

    public function getEndTime(): ?string
    {
        return $this->endTime;
    }

    public function setEndTime(string $endTime): self
    {
        $this->endTime = $endTime;

        return $this;
    }

    /**
     * @return Collection|EventDate[]
     */
    public function getEventDates(): Collection
    {
        return $this->eventDates;
    }

    public function addEventDate(EventDate $eventDate): self
    {
        if (!$this->eventDates->contains($eventDate)) {
            $this->eventDates[] = $eventDate;
            $eventDate->setEvent($this);
        }

        return $this;
    }

    public function removeEventDate(EventDate $eventDate): self
    {
        if ($this->eventDates->contains($eventDate)) {
            $this->eventDates->removeElement($eventDate);
            // set the owning side to null (unless already changed)
            if ($eventDate->getEvent() === $this) {
                $eventDate->setEvent(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|EventImage[]
     */
    public function getEventImages(): Collection
    {
        return $this->eventImages;
    }

    public function addEventImage(EventImage $eventImage): self
    {
        if (!$this->eventImages->contains($eventImage)) {
            $this->eventImages[] = $eventImage;
            $eventImage->setEvent($this);
        }

        return $this;
    }

    public function removeEventImage(EventImage $eventImage): self
    {
        if ($this->eventImages->contains($eventImage)) {
            $this->eventImages->removeElement($eventImage);
            // set the owning side to null (unless already changed)
            if ($eventImage->getEvent() === $this) {
                $eventImage->setEvent(null);
            }
        }

        return $this;
    }

}

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\EventImageRepository")
 */
class EventImage
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $url;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Event", inversedBy="eventImages")
     */
    private $event;

    public function getId()
    {
        return $this->id;
    }

    public function getUrl(): ?string
    {
        return $this->url;
    }

    public function setUrl(?string $url): self
    {
        $this->url = $url;

        return $this;
    }

    public function getEvent(): ?Event
    {
        return $this->event;
    }

    public function setEvent(?Event $event): self
    {
        $this->event = $event;

        return $this;
    }
}

Я не могу выяснить, чего мне не хватает или возможно ли этого добиться с помощью сериализатора по умолчанию от Symfony.

...