2010-08-05 5 views
12

Morgen Jungs,C# XML Serialisieren Liste <T> Nachkomme mit XML-Attribut

Ich habe eine Sammlung, die aus Liste absteigt und verfügt über ein öffentliches Eigentum. Der Xml-Serializer greift nicht auf meine Erfahrung zurück. Die Listenelemente werden ordnungsgemäß serialisiert. Ich habe das XmlAttribute-Attribut vergeblich versucht. Habt ihr eine Lösung?

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 
    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     var people = new PersonCollection 
     { 
      new Person { FirstName="Sue", Age=17 }, 
      new Person { FirstName="Joe", Age=21 } 
     }; 
     people.FavoritePerson = "Sue"; 

     var x = new XmlSerializer(people.GetType()); 
     var b = new StringBuilder(); 
     var w = XmlTextWriter.Create(b, new XmlWriterSettings { NewLineChars = "\r\n", Indent = true }); 
     x.Serialize(w, people); 
     var s = b.ToString(); 
    } 
} 

[XmlRoot(ElementName="People")] 
public class PersonCollection : List<Person> 
{ 
    //DOES NOT WORK! ARGHHH 
    [XmlAttribute] 
    public string FavoritePerson { get; set; }  
} 

public class Person 
{ 
    [XmlAttribute] 
    public string FirstName { get; set; } 
    [XmlAttribute] 
    public int Age { get; set; } 
} 

Ich erhalte das folgende XML-

<?xml version="1.0" encoding="utf-16"?> 
     <People xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
      <Person FirstName="Sue" Age="17" /> 
      <Person FirstName="Joe" Age="21" /> 
     </People> 

Ich möchte diese

<?xml version="1.0" encoding="utf-16"?> 
     <People FavoritePerson="Sue" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
      <Person FirstName="Sue" Age="17" /> 
      <Person FirstName="Joe" Age="21" /> 
     </People> 

Antwort

4

ich ging voran kommen und das Problem gelöst durch IXmlSerializable implementieren. Wenn eine einfachere Lösung existiert, poste es! Diese

[XmlRoot(ElementName="People")] 
public class PersonCollection : List<Person>, IXmlSerializable 
{ 
    //IT WORKS NOW!!! Too bad we have to implement IXmlSerializable 
    [XmlAttribute] 
    public string FavoritePerson { get; set; } 

    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     return null; 
    } 
    public void ReadXml(XmlReader reader) 
    { 
     FavoritePerson = reader[0];    
     while (reader.Read()) 
     { 
      if (reader.Name == "Person") 
      { 
       var p = new Person(); 
       p.FirstName = reader[0]; 
       p.Age = int.Parse(reader[1]); 
       Add(p); 
      } 
     } 
    } 
    public void WriteXml(XmlWriter writer) 
    { 
     writer.WriteAttributeString("FavoritePerson", FavoritePerson); 
     foreach (var p in this) 
     { 
      writer.WriteStartElement("Person"); 
      writer.WriteAttributeString("FirstName", p.FirstName); 
      writer.WriteAttributeString("Age", p.Age.ToString()); 
      writer.WriteEndElement();    
     } 
    } 
} 
+0

Steve können Sie Ihre eigenen Antworten akzeptieren. – nawfal

4

ist keine Antwort auf die Frage, aber ich dachte, dass ich einen Vorschlag in der Code-Entwicklung zu erleichtern machen würde.

ein neues Add Verfahren zum PersonCollection Klasse als solche hinzufügen:

public class PersonCollection : List<Person>, IXmlSerializable 
{ 
... 
    public void Add(string firstName, int age) 
    { 
     this.Add(new Person(firstName, age)); 
    } 
... 
} 

Dann dies tun, können Sie Ihre Auflistungsinitialisierer Syntax vereinfachen:

var people = new PersonCollection 
{ 
    { "Sue", 17 }, 
    { "Joe", 21 } 
}; 
people.FavoritePerson = "Sue"; 
+0

Cooler Trick. Vielen Dank! – Steve

1

Wenn Sie nicht tun Denken Sie daran, alle Listenfunktionen zu umbrechen, dann können Sie die Liste als eine Eigenschaft der Klasse einbetten, anstatt von ihr abzuleiten.

Mit dem XmlElement-Attribut erzwingen Sie, dass die XML-Elemente als flache Liste ausgegeben werden (anstatt verschachtelt zu sein).

Verwandte Themen