Support for serializing arrays to XML #59

Closed
Seldaek opened this Issue Dec 18, 2011 · 18 comments

Projects

None yet

8 participants

@Seldaek

Example of desired output:

Granted that $game is an object.

$data = array(
    'game' => $game,
    'players' => array(
        'Alice',
        'Bob',
    ),
);
<results>
    <game>
        <id>3</id>
        <name>Foo</name>
    </game>
    <players>
        <entry>Alice</entry>
        <entry>Bob</entry>
    </players>
</results>

To name xml elements, distinction between lists (players) and maps (the top-level array) could be done by using isset($array[0]), or alternatively ìs_numeric($key) on every key to know if it should be called $key or entry.

@schmittjoh
Owner

This output can be achieved using the following class:

<?php

/** @XmlRoot("results") */
class Result
{
    private $game;

    /** @XmlList */
    private $players;

    public function __construct(Game $game, array $players) 
    {
        $this->game = $game;
        $this->players = $players;
    }
}

We can try to make the default array encoding smarter. If someone wants to provide a patch, that would be welcome.

@Seldaek

I have a real use case for this now btw.. not just laziness, but a dynamic array of arbitrary user data (sort of a key-value store) that I have to return as XML. It does not seem possible :/

@schmittjoh
@Seldaek

Well I serialize $player and that is an object so the main properties go well, but then one of the properties is an array containing arbitrary data like array('foo' => array('bar' => 'baz')).

The output goes like:

<player>
    <name>Foo</name>
    <details>
        <entry>
            <entry>baz</entry>
        </entry>
    </details>
</player>

Those <entry> tag are really useless.. I don't know in which case they make sense, but surely in this one it is destructive and I can't build objects to map it since the details data structure is not in my hands.

@schmittjoh
Owner

What Output would you expect?

@michelsalib

AFAIK there is two suitable options. Lets take this array:

<?php
$data = array(
    'name' => 'Fabien',
    'gender' => 'male',
    'Symfony2 developer'
);
  • 1 using the key as the tag name:
<data>
    <name>Fabien</name>
    <gender>male</gender>
    <entry>Symfony2 developer</entry>
</data>
  • 2 Add a key attribute the the entry tag:
<data>
    <entry key="name">Fabien</entry>
    <entry key="gender">male</entry>
    <entry>Symfony2 developer</entry>
</data>
@michelsalib

I should add that the second options looks much cleaner. This way you can easily see that you are dealing with an array, and there is no ambiguity about the model you are exposing.

Whatever, maybe we should look into a set of metadata dedicated to dealing with array in order to allow both options.

@schmittjoh
Owner

The second option should already be possible if @XmlMap is added to the property.

@michelsalib

Arf, I missed it. Is it making this issue invalid ?

@Seldaek

I still think the first option should be possible as well because that's how it looks in JSON, and that's how it would look if I could expose it as an object with properties. The fact that PHP arrays can be both arrays and hashes should not be reflected in the API output IMO. If I have a hash, I want it output as a hash, not as a bunch of entry tags, no matter if they have a key attribute or not.

@justfortier

I agree with Seldaek. If I have a hash I expect that those keys get turned into tags, similar to how an object is treated. My 2 cents.

This was referenced Mar 15, 2012
@borisguery

I agree too. However I think that the entry tags is used because using a digit as a tag element is not valid against an XML document.

The XML spec defines it with NameStartChar which didn't include digits.

@Spea

What is the state of this issue? Like @Seldaek already mentioned, I also think this would be quite useful.
I could implement such functionality, maybe by adding an extra option to the XmlMap annotation?

@schmittjoh
Owner

How about making an extra annotation? You don't need any of the options like "keyAttribute", etc. which are currently on the @XmlMap annotation.

@Spea

Ok, makes sense. What about @XmlArray?

@schmittjoh
Owner

Not sure, I don't have a good name for now, but we can start with @XmlArray, it should be easy to change at a later point.

@schmittjoh schmittjoh closed this Jul 2, 2012
@Wirone

Is it possible to serialize array without having object with @XmlKeyValuePairs annotation? Just like @Seldaek wrote in first post, if I have raw array and I want serialize it to xml directly, how to achieve it?

@jeanCarloMachado

I'm struggling with the same problem as @Wirone. I need xml tags by array indices, there's some news about this problem? An official way of doing it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment