C# sérialisation Xml, de la collecte et de l'élément racine

Mon application sérialise les objets dans les cours d'eau.
Voici un échantillon de ce dont j'ai besoin :

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

Dans ce cas, l'objet est une collection de "liens" de l'objet.

-----------Première version

Au début, j'ai utilisé le DataContractSerializer, mais vous ne pouvez pas sérialiser les membres comme des attributs (source)

Voici l'objet :

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

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

Et voici le résultat :

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

----------- Deuxième version

Ok, pas tranquille ce que je veux, alors j'ai essayé le classique XmlSerializer, mais... oh nooon, vous ne pouvez pas spécifier le nom de l'élément racine & des éléments de la collection si l'élément racine est une collection...

Voici le code :

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

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

Voici le résultat :

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

----------- Troisième version

à l'aide de XmlSerializer + un élément racine :

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

Et de son résultat :

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

Gentil, mais je ne veux pas que le nœud racine !!
Je veux que ma collection soit le nœud racine.

Voici les contraintes :

  • le code de sérialisation est générique, il fonctionne avec quoi que ce soit sérialisable
  • l'opération inverse (de la désérialisation) ont à travailler trop
  • Je ne veux pas regex le résultat (je sérialiser directement dans un flux de sortie)

Quelles sont mes solutions :

  1. Codage mon propre XmlSerializer
  2. Truc XmlSerializer, quand il travaille avec une collection (j'ai essayé, d'avoir à trouver une XmlRootElement et plurialize à générer son propre attribut xmlrootattribute, mais qui provoque des problème lors de la désérialisation + le nom d'éléments conserve encore le nom de la classe)

Une idée ?

Vraiment ce qui me dérange dans cette question, c'est que ce que je veux semble être vraiment vraiment vraiment simple...

Je triche, et sérialiser "comme elle vient", puis appliquer une transformation xsl pour le xml résultant de massage à ce que vous avez besoin. Sinon, avez-vous regardé [MessageContract]? Il offre beaucoup plus d'options de personnalisation sur la sortie de DataContract
XSL tricher n'est pas une option, car le sérialiseur écrit directement dans un cours d'eau... et merci pour l' [MessageContract] plomb, j'ai appris quelque chose aujourd'hui ^^ cependant il est profondément liée à la WCF et ne permet pas de contrôler finement un simple Sérialisation XML (je me trompe peut-être, juste découvert l'attribut)

OriginalL'auteur Mose | 2012-08-02