C# Xml serialization, collection and root element

Viewed 21298

My app serializes objects in streams. Here is a sample of what I need :

<links>
  <link href="/users" rel="users" />
  <link href="/features" rel="features" />
</links>

In this case, the object is a collection of 'links' object.

-----------First version

At first I used the DataContractSerializer, however you cannot serialize members as attributes (source)

Here is the object :

[DataContract(Name="link")]
public class LinkV1
{
    [DataMember(Name="href")]
    public string Url { get; set; }

    [DataMember(Name="rel")]
    public string Relationship { get; set; }
}

And here is the result :

<ArrayOflink xmlns:i="...." xmlns="...">
  <link>
    <href>/users</href>
    <rel>users</rel>
  </link>
  <link>
    <href>/features</href>
    <rel>features</rel>
  </link>
</ArrayOflink>

----------- Second version

Ok, not quiet what I want, so I tried the classic XmlSerializer, but... oh nooo, you cannot specify the name of the root element & of the collection's elements if the root element is a collection...

Here is the code :

[XmlRoot("link")]
public class LinkV2
{
    [XmlAttribute("href")]
    public string Url { get; set; }

    [XmlAttribute("rel")]
    public string Relationship { get; set; }
}

Here is the result :

<ArrayOfLinkV2>
  <LinkV2 href="/users" rel="users" />
  <LinkV2 href="/features" rel="features" />
  <LinkV2 href="/features/user/{keyUser}" rel="featuresByUser" />
</ArrayOfLinkV2>

----------- Third version

using XmlSerializer + a root element :

[XmlRoot("trick")]
public class TotallyUselessClass
{
    [XmlArray("links"), XmlArrayItem("link")]
    public List<LinkV2> Links { get; set; }
}

And its result :

 <trick>
  <links>
    <link href="/users" rel="users" />
    <link href="/features" rel="features" />
    <link href="/features/user/{keyUser}" rel="featuresByUser" />
  </links>
</trick>

Nice, but I don't want that root node !! I want my collection to be the root node.

Here are the contraints :

  • the serialization code is generic, it works with anything serializable
  • the inverse operation (deserialization) have to work too
  • I don't want to regex the result (I serialize directly in an output stream)

What are my solutions now :

  1. Coding my own XmlSerializer
  2. Trick XmlSerializer when it works with a collection (I tried, having it find a XmlRootElement and plurialize it to generate its own XmlRootAttribute, but that causes problem when deserializing + the items name still keeps the class name)

Any idea ?

What really bother me in that issue, is that what I want seems to be really really really simple...

3 Answers
Related