Десериализация XML в объектный код не работает

У меня проблема с десериализацией и XML в Symfony. Я попробовал обычный сериализатор Symfony, но и там он не работает.

Насколько я вижу, все вроде правильно, но я не вижу проблемы.

Контроллер:

<?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');
    }
}

Приложение\DataObjects\Досье:


<?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;
    }
}

Приложение\DataObjects\Досье:

<?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;
    }
}

Возврат на данный момент:

Source:
Type:
Dossiers:

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

Я хочу, чтобы XML был помещен в DataObjects, чтобы я мог использовать DataObject позже для более сложных задач.

Вы показали нам код и рассказали, какова ваша цель, но вы не рассказали нам, в чем на самом деле заключается «проблема», с которой вы столкнулись. Что происходит, когда вы посещаете маршрут '/test/' ?

Arleigh Hix 16.05.2024 06:18

Ой, извини. На самом деле происходит то, что я ничего не получаю обратно. Возвращаемое значение для приведенного выше кода в Symfony 7 следующее: Источник: Тип: Досье: App\DataObjects\Dossiers {#146 ▼ -source: null -type: null -dossiers: [] }

Illmaren 16.05.2024 08:13

Пробовали ли вы сериализовать, чтобы дважды проверить структуру совпадений xml? Я думаю, может, нужно завернуть предметы в поле? <Dossiers ... ><dossiers><Dossier></...>

Arleigh Hix 16.05.2024 09:08

XML не создан мной, а предоставлен мне, и я не могу ничего изменить в структуре XML. Это <Досье ...><Досье></Досье></Досье> Я бы даже не стал создавать эту структуру, поскольку Досье всегда одно.

Illmaren 16.05.2024 09:13

Хорошо, я нашел несколько подходящих примеров, но это (обратный пример теста) будет способом проверить, что все настроено правильно.

Arleigh Hix 16.05.2024 09:19

Кажется, у нас здесь что-то есть. $testDossiers = новые досье('TestSource', 'TestType', новое досье('TestName')); создает: <?xml version = "1.0"coding = "UTF-8"?> <result source = "TestSource" type = "TestType"> <Name><![CDATA[TestName]]></Name> </ result> Что выглядит как-то неправильно.

Illmaren 16.05.2024 09:35
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
6
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел проблему.

Сериализатор JMS дает вам немного больше аннотаций, чем я использовал. Поэтому я добавил XmlRoot и XmlNamespace в начале первого класса, чтобы правильно обрабатывать весь XML. теперь это работает.

<?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")
     */

Ваши пользовательские теги XML не являются допустимыми для ATOM. Я предлагаю вам использовать собственное пространство имен (uri) и префикс.

ThW 16.05.2024 11:16

Я использую свой собственный, просто изменил его на Atom, чтобы сделать его анонимным.

Illmaren 04.06.2024 12:26

Другие вопросы по теме