Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用属性序列化XML文档_Php_Xml_Symfony_Serialization - Fatal编程技术网

Php 使用属性序列化XML文档

Php 使用属性序列化XML文档,php,xml,symfony,serialization,Php,Xml,Symfony,Serialization,我试图序列化一个XML文档,其中包含要插入MySQL数据库的实体 例如,我在实体中获得了以下两个属性: $companyId $companyName 问题在于,我的XML文档中没有这样的内容: <company> <id>8888</id> <name>MyCompany</name> </company> 8888 我的公司 我得到了这样的东西: <company id="8888" na

我试图序列化一个XML文档,其中包含要插入MySQL数据库的实体

例如,我在实体中获得了以下两个属性:

  • $companyId
  • $companyName
问题在于,我的XML文档中没有这样的内容:

<company>
    <id>8888</id>
    <name>MyCompany</name>
</company>

8888
我的公司
我得到了这样的东西:

<company id="8888" name="MyCompany"/>

XML是由我工作的一家独立公司生成的;所以我不能改变它。 因此Symfony2序列化程序正在创建一个空的
$company
属性:(

有没有一种简单的方法可以像我所希望的那样降低血清化过程的成本?或者我必须实现一个完全独立的方法

非常感谢。

我会创建一个简单的,因为默认情况下属性已经被解析。它会在键的旁边添加一个特殊字符
@

不需要做很多调整,您就可以添加一个上下文参数,如
use\u attributes
,这是您的自定义反规范化程序可以理解的

use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

class AttributesDenormalizer implements DenormalizerInterface
{
    public function __construct(DenormalizerInterface $delegate)
    {
        $this->delegate = $delegate;
    }

    public function denormalize($data, $class, $format = null, array $context = array())
    {
        if (!is_array($data) || !isset($context['use_attributes']) || true !== $context['use_attributes']) {
            return $this->delegate->denormalize($data, $class, $format, $context);
        }

        $attributes = array();

        foreach ($data as $key => $value) {
            if (0 === strpos($key, '@')) {
                $attributes[substr($key, 1)] = $value;
            }
        }

        if (empty($attributes)) {
            $attributes = $data;
        }

        return $this->delegate->denormalize($attributes, $class, $format, $context);
    }

    public function supportsDenormalization($data, $type, $format = null)
    {
        return $this->delegate->supportsDenormalization($data, $type, $format);
    }
}
下面是一个用法示例

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;

$xml = '<company id="8888" name="MyCompany"/>';

$encoders = array(new XmlEncoder());
$normalizers = array(new AttributesDenormalizer(new GetSetMethodNormalizer));

$serializer = new Serializer($normalizers, $encoders);
$serializer->deserialize($xml, 'Company', 'xml', array('use_attributes' => true));

好的,所以最后我尝试使用JMSSerializerBundle,但我的情况太复杂了。我得到了许多实体,它们具有多个manytone关系;我在XML中得到了bot标准和属性值

所以我将使用你的想法:创建我完整的反规范化程序。它将使用解码后的XML并逐行读取它,做它必须做的事情(用条令创建实体)

这将是一个巨大的过程,但最简单的一个

多谢各位

[编辑]我终于找到了一个很好的解决方案。 我将XML和实体设置器之间的链接注册到yaml表中

company:
    @id: setCompanyId
    @name : setCompanyName
    address:
        @city: setAddressCity
        @street: setAddressStreet
...
有鉴于此,我可以轻松地读取整个XML,对于每个节点/属性值,在表中找到setter名称,然后执行以下操作:

$company = new Company;
$company->setterNameFromTable($value);
通过使用带有“@”的@SerializeName注释,现在序列化XML属性要容易得多

在公司实体中,定义$name时,添加

/**
*@ORM\Column(type=“string”,长度=255)
*@SerializedName(“@name”)
*/
私人$name;
现在,当您序列化为XML时,它将如预期的那样作为属性出现


我知道OP实际上是在询问反序列化的问题,但希望这对正在搜索的人有所帮助。

好的,我明白了。但这有点复杂,因为我可以在同一个XML文件中有多个
,而且我还必须管理关系……我想我必须使用JMSSerializerBundle!这确实是一个很好的选择,可以让更多的合作伙伴参与进来复杂案例(对象数组、深度序列化…)。但是,通过给出的示例,可以轻松地管理简单的对象数组。是的,非常感谢您的示例;我正在尝试几种解决方案,我会让您知道哪一种是最好的。好的,我刚刚查看了JMSSerializerBundle。它允许通过注释系统进行许多操作,但它无法从本质上解决我的问题……我想我会的必须创建自己的处理程序来修复它。
$company = new Company;
$company->setterNameFromTable($value);