phpxmlsymfonyserializationxml-parsing

Deserializing a XML into an Object code does not work


I have a issue with deserializing and XML within Symfony. I tried the normal Symfony Serializer but its not working there either.

As far as I can see everyting seems to be correct but I dont see the issue.

Controller:

<?php

namespace App\Controller;

use App\DataObjects\Dossiers;
use JMS\Serializer\SerializerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

#[Route('/test')]
class TestController extends AbstractController
{
    private $serializer;

    public function __construct(SerializerInterface $serializer)
    {
        $this->serializer = $serializer;
    }

    #[Route('/')]
    public function test(): Response
    {
        $xmlContent = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <Dossiers source="Source" type="myType">
            <Dossier>
                <Name>Name</Name>
                <Description>Description</Description>
            </Dossier>
        </Dossiers>';

        // Deserialisieren Sie den XML-Inhalt
        $dossiers = $this->serializer->deserialize($xmlContent, Dossiers::class, 'xml');

        // Debugging
        echo "Source: " . $dossiers->getSource() . "<br>";
        echo "Type: " . $dossiers->getType() . "<br>";
        echo "Dossiers:<br>";
        foreach ($dossiers->getDossiers() as $dossier) {
            echo "  Name: " . $dossier->getName() . "<br>";
            echo "  Description: " . $dossier->getDescription() . "<br>";
        }

        dd($dossiers);
        return new Response('Parsed XML');
    }
}

App\DataObjects\Dossiers:


<?php
namespace App\DataObjects;

use JMS\Serializer\Annotation as JMS;

/**
 * @JMS\XmlRoot("Dossiers")
 */
class Dossiers
{
    /**
     * @JMS\XmlAttribute
     * @JMS\SerializedName("source")
     * @JMS\Type("string")
     */
    private $source;

    /**
     * @JMS\XmlAttribute
     * @JMS\SerializedName("type")
     * @JMS\Type("string")
     */
    private $type;

    /**
     * @JMS\SerializedName("Dossier")
     * @JMS\Type("array<App\DataObjects\Dossier>")
     * @JMS\XmlList(inline = true, entry = "Dossier")
     */
    private $dossiers = [];

    public function getSource()
    {
        return $this->source;
    }

    public function setSource($source)
    {
        $this->source = $source;
    }

    public function getType()
    {
        return $this->type;
    }

    public function setType($type)
    {
        $this->type = $type;
    }

    public function getDossiers()
    {
        return $this->dossiers;
    }

    public function setDossiers(array $dossiers)
    {
        $this->dossiers = $dossiers;
    }
}

App\DataObjects\Dossier:

<?php

namespace App\DataObjects;

use JMS\Serializer\Annotation as JMS;

class Dossier
{
    /**
     * @JMS\XmlElement(cdata=false)
     * @JMS\SerializedName("Name")
     * @JMS\Type("string")
     */
    private $name;

    /**
     * @JMS\XmlElement(cdata=false)
     * @JMS\SerializedName("Description")
     * @JMS\Type("string")
     */
    private $description;

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

    public function setName($name)
    {
        $this->name = $name;
    }

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

    public function setDescription($description)
    {
        $this->description = $description;
    }
}

Return at the moment:

Source:
Type:
Dossiers:

 App\DataObjects\Dossiers {#146 ▼
  -source: null
  -type: null
  -dossiers: []
}

What I want is for the XML to be put into the DataObjects so that I can use the DataObject later for more complex stuff.


Solution

  • I Found the problem.

    The JMS Serializer gives you a bit more Annotation then I used. So I added a XmlRoot and a XmlNamespace at the start of the first class to handle my whole XML correctly. now it works.

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
            <atom:Dossiers xmlns:atom="http://www.w3.org/2005/Atom" source="TestSource" type="TestType">
                <atom:Dossier>
                    <atom:Name>Name</atom:Name>
    
    #[JMS\XmlRoot("Dossiers")]
    #[JMS\XmlNamespace(uri:"http://www.w3.org/2005/Atom", prefix:"atom")]
    class Dossiers
    {
        /**
         * @JMS\XmlAttribute
         * @JMS\SerializedName("source")
         * @JMS\Type("string")
         */
        private $source;
    
        /**
         * @JMS\XmlAttribute
         * @JMS\SerializedName("type")
         * @JMS\Type("string")
         */
        private $type;
    
        /**
         * @JMS\SerializedName("Dossier")
         * @JMS\Type("App\DataObjects\Dossier")
         * @JMS\XmlElement(cdata=false, namespace="http://www.w3.org/2005/Atom")
         */