2009-07-11 7 views
3

J'ai le code suivant:noms de noeud personnalisé avec sérialisation XML (.NET)

public class Foo {} 

static class Program { 
    [XmlElement("foo")] // Ignored :(
    static public List<Foo> MyFoos { get; private set; } 

    public static void Main() { 
     MyFoos.Add(new Foo()); 
     MyFoos.Add(new Foo()); 

     XmlSerializer configSerializer = 
      new XmlSerializer(typeof(List<Foo>), new XmlRootAttribute("foos")); 
     using (TextWriter w = new StreamWriter("test.xml")) 
     { 
      s.Serialize(w, MyFoos); 
     } 
    } 
} 

qui produit le fichier XML suivant:

<?xml version="1.0" encoding="utf-8"?> 
<foos xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Foo /> 
    <Foo /> 
</foos> 

Ce que je voudrais vraiment avoir est le Foo Les éléments étiquetés foo, à la place ... Je réalise que c'est surtout cosmétique, mais cela correspond à ce qui est généralement considéré comme normal en XML.

Répondre

10

Il devrait fonctionner si vous définissez directement le nom de l'élément ...

[XmlElement(ElementName = "foo")] 

Voir l'exemple here. Est-ce que le point qu'il doit être statique? Si oui, ce n'est pas utile, mais cela fonctionne très bien (ajouté le commentaire par voyage aller-retour) ...

namespace TestSerial 
{ 
    public class Foo 
    { 
     public int Value 
     { 
      get; 
      set; 
     } 
    } 
    public class SerializeMe 
    { 
     private List<Foo> _foos = new List<Foo>(); 
     public SerializeMe() 
     { 
     } 

     [XmlElement("foo")] 
     public List<Foo> MyFoos { get { return _foos; } } 

    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var fs = new SerializeMe(); 
      fs.MyFoos.Add(new Foo() { Value = 1 }); 
      fs.MyFoos.Add(new Foo() { Value = 2 }); 

      var s = new XmlSerializer(typeof(SerializeMe), new XmlRootAttribute("foos")); 
      using (var w = new StreamWriter(@"c:\temp\test.xml")) 
      { 
       s.Serialize(w, fs); 
      } 

      using (var r = new StreamReader(@"c:\temp\test.xml")) 
      { 
       var o = s.Deserialize(r); 
       var fs2 = (SerializeMe)o; 

       fs2.MyFoos.Select(f => f.Value).ToList().ForEach(Console.WriteLine); 
      } 

      Console.ReadLine(); 
     } 
    } 
} 

EDIT: (Matthieu, OP)

Ma solution finale, que je considère un raffinement de ce qui précède était:

public class Foo {} 

[XmlRoot("foos")] 
public class FooList 
{ 
    public FooList() { Foos = new List<Foo>(); } 
    [XmlElement("foo")] 
    public List<Foo> Foos { get; set; } 
} 

static class Program 
{ 
    static private FooList _foos = new FooList(); 
    static public List<Foo> MyFoos { get { return _foos; } } 

    public static void Main() 
    { 
     MyFoos.Add(new Foo()); 
     MyFoos.Add(new Foo()); 

     XmlSerializer configSerializer = 
      new XmlSerializer(typeof(FooList)); 

     using (TextReader r = new StreamReader("test.xml")) 
     { 
      _foos = (FooList)configSerializer.Deserialize(r); 
     } 

     using (TextWriter w = new StreamWriter("test.xml")) 
     { 
      configSerializer.Serialize(w, _foos); 
     } 
    } 
} 
+1

XmlElementAttribute n'est pas autorisé sur les définitions de classe: L'attribut 'XmlElement' n'est pas valide pour ce type de déclaration. Il n'est valable que pour les déclarations 'property, indexer, field, param, return'. –

+0

Il l'a sur une propriété, non? –

+1

C'est une propriété statique et sera toujours ignorée. –

Questions connexes