1

I am using Symfony2 and trying to serialize different collections of objects into XML. For the sake of brevity, let's assume I am trying to list and unlist entities and this is the XML I want to get as a result:

<?xml version="1.0" encoding="UTF-8"?>
<r someattribute="value">
    <data_list>
        <item id="9" type="a"><![CDATA[list data 1]></item>
        <item id="10" type="a"><![CDATA[list data 2]></item>
        <item id="11" type="b"><![CDATA[list data 3]></item>
    </data_list>
    <data_unlist>
        <uitem id="9" type="a" />
    </data_unlist>
</r>

Here are my classes: Item for the "item" nodes, Uitem for the "uitem" nodes and Model, to contain them all:

class Item
{
    private $data=array();
    public function getData() {return $this->data;}

    public function __construct($id, $type, $value)
    {
        $this->data["@id"]=$id;
        $this->data["@type"]=$type;
        //How do I put $value as the node value????
    }
}

class UItem
{
    private $data=array();
    public function getData() {return $this->data;}

    public function __construct($id, $type)
    {
        $this->data["@id"]=$id;
        $this->data["@type"]=$type;
    }
}

class Model
{
    private $data_list=array();
    private $data_unlist=array();

    public function getDataList() {return $this->data_list;}
    public function getDataUnlist() {return $this->data_unlist;}

    public function __construct()
    {
        $this->data_list[]=new Item(9, 'a', 'list data 1');
        $this->data_list[]=new Item(10, 'a', 'list data 2');
        $this->data_list[]=new Item(11, 'b', 'list data 3');

        $this->data_unlist[]=new UItem(9, 'a');
    }
}

Save for the problem I left commented in the Item class (how to put the node value there) I think that should serialize correctly so...

$model=new Model();
$encoders=array(new XmlEncoder());
$normalizers=array(new GetSetMethodNormalizer());
$serializer=new Serializer($normalizers, $encoders);
$contents_xml=$serializer->serialize($model, 'xml');

This is the result I am getting:

<response>
    <data_list>
        <item id="9" type="a" />
    </data_list>
    <data_list>
        <item id="11" type="b" />
    </data_list>
    <data_unlist>
        <uitem id="9" type="a" />
    </data_unlist>
</response>

As you can see, two separate nodes for "data_list" have been created instead of grouping them into one single node.

Here are my questions:

  • Can I put the two "item" into a single "data_list"?. If so, how?.
  • How can I specify the value of a item node (instead of its attributes only) preserving the desired structure?.
  • How do I alter the root node name and add attributes to it?.

For the record, I am using the vanilla serializer, no JMS here.

Thanks in advance.

2 Answers 2

5

Using Symfony XmlEncoder I am able to build an array and turn it into xml using the encode method. Any array items which are named as @something are turned into attributes of the wrapping element rather than child elements, so:

$encoder = new \Symfony\Component\Serializer\Encoder\XmlEncoder();
$data = [
  'something' => [
    '@foo' => 'bar',
    'yoo' => 'bar',
  ]
];
$xml = $encoder->encode($data, 'xml');

Gives me:

<?xml version="1.0"?>
<response>
  <something foo="bar">
    <yoo>bar</yoo>
  </something>
</response>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Duncan moo. This came a bit late but now that I am into symfony again I may find it useful :).
1

JMSSerializer was created for these purposes. And I think you should start to use it in your project. It has no overhead and is easy to use.

You can control your serializing options with annotations: http://jmsyst.com/libs/serializer/master/reference/annotations

4 Comments

Thanks Michael... I am almost new to Symfony and still it is a bit overwhelming. I will take a look at the documentation and see if it supports the yml annotations we're using on this project. Thanks again.
You can use yml annotations for doctrine-mapping but annotations for JMSSerializer. But JMSSerializer can handle xml and yml configurations if you like it.
Absolutely wonderful: got it working in 30 minutes using annotations with no problems. Quick, easy and very powerful!.
However JMSSerializer is very good, I used to use it before, I'm using Serializer Component that is part of Symfony symfony.com/doc/current/components/serializer.html. Works well for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.