Symfony Serializer - Как сгруппировать массив объектов? - PullRequest
0 голосов
/ 03 января 2019

Мне нужно создать XML-файл с «сгруппированными» элементами, например, атрибутов.
У меня есть образцы классов объектов:
Продукт

class Product
{
    private $name;
    private $attributes = [];

    // standard getter/setter for name

    public function getAttributes(): array
    {
        return $this->attributes;
    }

    public function setAttributes(ProductAttribute $attributes): void
    {
        $this->attributes[] = $attributes;
    }
}

и ProductAttribute

class ProductAttribute
{
    private $name;
    private $value;

    // standard getters/setters
}

Теперь я создаю Product объект и сериализую его с помощью сериализатора Symfony:

$product = new Product();
$product->setName('My product');

foreach ($arrayWithAttributes as $attr) {
    $attribute = new ProductAttribute();
    $attribute->setName = $attr['name'];
    $attribute->setValue = $attr['value'];

    $product->setAttributes($attribute);
}

$encoders = array(new XmlEncoder());
$normalizers = array(new ObjectNormalizer());

$serializer = new Serializer($normalizers, $encoders);
$serializer->serialize($product, 'xml');

И я получаю результат:

    <item key="0">
        <name>My product</name>
        <attributes>
            <name>Attribute Name #1</name>
            <value>Attribute Value #1</value>
        </attributes>
        <attributes>
            <name>Attribute Name #2</name>
            <value>Attribute Value #2</value>
        </attributes>
    </item>

но я ожидаю:

    <item key="0">
        <name>My product</name>
        <attributes>
            <attribute>
                <name>Attribute Name #1</name>
                <value>Attribute Value #1</value>
            </attribute>
            <attribute>
                <name>Attribute Name #2</name>
                <value>Attribute Value #2</value>
            </attribute>
        </attributes>
    </item>

Как я могу получить это?
Я уже пробовал с:

//Product.php
public function setAttributes(ProductAttribute $attributes)
{
    $this->attributes[]['attribute'] = $attributes;
}

но тогда я получаю:

    <item key="0">
        <name>My product</name>
        <attributes>
            <attribute>
                <name>Attribute Name #1</name>
                <value>Attribute Value #1</value>
            </attribute>
        </attributes>
        <attributes>
            <attribute>
                <name>Attribute Name #2</name>
                <value>Attribute Value #2</value>
            </attribute>
        </attributes>
    </item>

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Хорошо, я получил это - мне пришлось добавить ArrayDenormalizer для нормализаторов для поддержки вложенного дерева и изменить установщик свойства Product $attributes.Наконец-то выглядит:

class Product
{
    private $name;
    private $attributes = [];

    // standard getter/setter for name

    public function getAttributes(): array
    {
        return $this->attributes;
    }

    public function setAttributes(ProductAttribute $attributes): void
    {
        $this->attributes['attribute'][] = $attributes;
    }
}

class ProductAttribute
{
    private $name;
    private $value;

    // standard getters/setters
}

use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

$product = new Product();
$product->setName('My product');

foreach ($arrayWithAttributes as $attr) {
    $attribute = new ProductAttribute();
    $attribute->setName = $attr['name'];
    $attribute->setValue = $attr['value'];

    $product->setAttributes($attribute);
}

$encoders = array(new XmlEncoder());
$normalizers = array(new ObjectNormalizer(), new ArrayDenormalizer());

$serializer = new Serializer($normalizers, $encoders);
$serializer->serialize($product, 'xml');
0 голосов
/ 03 января 2019

попробуйте это

$attrArray = [];

foreach ($arrayWithAttributes as $attr) {
    $attribute = new ProductAttribute();
    $attribute->setName = $attr['name'];
    $attribute->setValue = $attr['value'];
    $attrArray[] = $attribute;

}

 $product->setAttributes($attrArray);

тогда в вашей организации

$this->attributes['attribute'] = $attributes;
...