Мне нужно создать 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>
попробуйте это пожалуйста
$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;
Хорошо, я получил это — я должен был добавить 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');