You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony中XML反序列化失败问题求助

Symfony XML反序列化失败:对象属性全部为null

问题描述

在Symfony框架中尝试XML反序列化,先后使用Symfony原生Serializer和JMS Serializer,结果生成的Dossiers对象的source、type、dossiers属性均为null。代码配置看起来无问题,期望XML数据能正确映射到数据对象,以便后续业务处理。

相关代码

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>';

        // 反序列化XML内容
        $dossiers = $this->serializer->deserialize($xmlContent, Dossiers::class, 'xml');

        // 调试输出
        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;
    }
}

当前返回结果

Source:
Type:
Dossiers:

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

排查与解决方法

1. 修复注解冲突

Dossiers类的dossiers属性同时使用了@JMS\SerializedName("Dossier")和@JMS\XmlList,二者存在冲突。XmlList已通过entry = "Dossier"指定了节点名称,移除多余的SerializedName注解即可:

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

2. 修正XML格式问题

原XML字符串包含多余缩进,可能导致解析异常,移除多余缩进后确保结构正确:

$xmlContent = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Dossiers source="Source" type="myType">
    <Dossier>
        <Name>Name</Name>
        <Description>Description</Description>
    </Dossier>
</Dossiers>';

3. 明确注入JMS Serializer服务

若同时存在Symfony原生Serializer,需在构造函数中明确指定注入JMS的Serializer:

use JMS\Serializer\SerializerInterface as JMSSerializerInterface;

// ...

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

4. 清除缓存

Symfony注解缓存可能导致修改不生效,执行以下命令清除缓存:

php bin/console cache:clear

完成以上步骤后,XML数据即可正确映射到Dossiers对象中。

内容的提问来源于stack exchange,提问作者Illmaren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 00:25:08