2010-02-18 16 views
29

Ich habe eine Klasse PersonListXmlSerializer Liste Artikel Elementname

[XmlRoot("Persons")] 
PersonList : List<Human> 

wenn ich die XML-Serialisierung, standardmäßig wird es so etwas wie diese produzieren:

<Persons> 
    <Human>...</Human> 
    <Human>...</Human> 
</Persons> 

Meine Frage ist, was sein muss getan, um das Element Human zu Person im Ausgang zu ändern? so dass der Ausgang wäre:

<Persons> 
    <Person>...</Person> 
    <Person>...</Person> 
</Persons> 

und, wie deserialisiert das oben XML zum PersonList Klassenobjekt?

Per Nicks Beratung, hier mein Testcode:

[XmlRoot("Persons")] 
public class Persons : List<Human> 
{ 

} 

[XmlRoot("Person")] 
public class Human 
{ 
    public Human() 
    { 
    } 

    public Human(string name) 
    { 
     Name = name; 
    } 

    [XmlElement("Name")] 
    public string Name { get; set; } 

} 

void TestXmlSerialize() 
{ 
    Persons personList = new Persons(); 
    personList.Add(new Human("John")); 
    personList.Add(new Human("Peter")); 

    try 
    { 
     using (StringWriter writer = new StringWriter()) 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(Persons)); 
      XmlWriterSettings settings = new XmlWriterSettings(); 
      settings.OmitXmlDeclaration = true; 

      XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); 
      namespaces.Add(string.Empty, string.Empty); 

      XmlWriter xmlWriter = XmlWriter.Create(writer, settings); 
      serializer.Serialize(xmlWriter, personList, namespaces); 

      Console.Out.WriteLine(writer.ToString()); 
     } 
    } 
    catch (Exception e) 
    { 
     Console.Out.WriteLine(e.ToString()); 
    } 
} 

Der Ausgang des Testcode lautet:

<Persons> 
    <Human> 
    <Name>John</Name> 
    </Human> 
    <Human> 
    <Name>Peter</Name> 
    </Human> 
</Persons> 

Wie die Ausgabe zeigt, die [XmlRoot("Person")] auf Human nicht den Tag ändern zu Person von Human.

+0

tribe84 richtige Antwort geschrieben ... – lanicor

+0

Mein Problem war, dass das Array intern markiert wurde – Nick

Antwort

22

Ich glaube nicht, dass es eine Möglichkeit für Sie gibt, den Namen der generierten Array-Elemente zu steuern.

Wenn Sie jedoch die Persons Sammlung in eine andere Klasse einbetten können, haben Sie dann die vollständige Kontrolle über die generierte Ausgabe mit XmlArrayAttribute und XmlArrayItemAttribute.

Wenn Sie diese neue Klasse nicht erstellen können, können Sie IXmlSerializable implementieren, aber das ist viel komplexer.

Ein Beispiel für die erste Alternative folgt:

[XmlRoot("Context")] 
public class Context 
{ 
    public Context() { this.Persons = new Persons(); } 

    [XmlArray("Persons")] 
    [XmlArrayItem("Person")] 
    public Persons Persons { get; set; } 
} 

public class Persons : List<Human> { } 

public class Human 
{ 
    public Human() { } 
    public Human(string name) { Name = name; } 
    public string Name { get; set; } 
} 

class Program 
{ 
    public static void Main(string[] args) 
    { 
     Context ctx = new Context(); 
     ctx.Persons.Add(new Human("john")); 
     ctx.Persons.Add(new Human("jane")); 

     var writer = new StringWriter(); 
     new XmlSerializer(typeof(Context)).Serialize(writer, ctx); 

     Console.WriteLine(writer.ToString()); 
    } 
} 
+0

Joao hat es richtig, wenn Sie die XML-Attribute verwenden möchten, die Sie benötigen, um Ihre Arrays zu rooten. –

+0

Für eine Lösung ohne eine Kontextklasse (mit der für mich nicht infrage kam) siehe @ tribe84 Antwort unten [http://stackoverflow.com/a/7812831/386546](http://stackoverflow.com/a/ 7812831/386546) –

3

Stellen Sie den XmlRoot Menschen zu:

[XmlRoot("Person")] 

Sidebar:

Personen sollte wohl Menschen

+4

Das funktioniert, wenn die Human-Klasse direkt serialisiert wird und nicht als untergeordnetes Element beim Serialisieren der Personenklasse funktioniert. – Qstonr

1

sein, wenn Sie Zugriff auf die Quelle nicht für haben die Klasse Mensch (in diesem Fall ist das Setzen von XmlRoot nicht möglich), können Sie ein XmlElementAttribute erstellen, Fügen Sie es dann einem XmlAttributeOverride hinzu und verwenden Sie dieses, wenn Sie eine Instanz Ihres XmlSerializers erstellen. See this MSDN article for more details.

+0

@Nick: +1: Um eine Alternative zu bieten, wenn er keinen Zugang zu "Human" hat, habe ich das nicht berücksichtigt. Eine andere, etwas weniger aufwendige Lösung für diesen Fall wäre, Human (vorausgesetzt, erlaubt) als Basis in einer neuen Klasse zu verwenden und den XmlRoot dort zu setzen. Es ist hackish aber ... :-) –

+0

Danke, aber ich kann nicht scheinen, es zu arbeiten. Ich frage mich, ob ich versuche, den Elementnamen für die Elemente in einer generischen Liste zu überschreiben, anstatt ein Mitglied eines Objekts zu überschreiben. – Qstonr

+1

@Qstonr - Ich würde vorschlagen, die Frage mit dem Code zu aktualisieren, den Sie versucht haben, Arbeit zu machen. Es ist wirklich schwierig, Fehler zu beheben, ohne dass der Code überprüft werden muss. – Nick

12

ich das gleiche Problem mit meinem Serializer hatte. Keine der obigen Antworten hat genau funktioniert. Ich habe festgestellt, dass das XmlRoot-Attribut in der Human-Klasse ignoriert wird, da es nicht das Stammelement des Dokuments ist. Das Wrappen der Liste in einem Kontextobjekt war für mich keine Option, da ich das XML-Schema nicht ändern kann. Die Lösung besteht darin, die Personenklasse zu ändern. Anstatt eine generische Liste zu unterklassifizieren, wickeln Sie sie in ein Objekt ein und ändern, wie sie serialisiert wird.Siehe den folgenden Beispielcode:

[XmlRoot("Persons")] 
public class Persons 
{ 
    public Persons() 
    { 
     People = new List<Human>(); 
    } 

    [XmlElement("Person")] 
    public List<Human> People 
    { get; set; } 
} 

public class Human 
{ 
    public Human() 
    { 
    } 

    public Human(string name) 
    { 
     Name = name; 
    } 

    [XmlElement("Name")] 
    public string Name { get; set; } 
} 

Serialisierung Ihre allgemeine Liste XmlElement mit bedeutet, dass es nicht das Hüllenelement um Ihre Liste gesetzt wird wie XmlArray tut oder wie die Subklassifizieren tut. Es gibt Ihnen auch die Bonusoption von Attributen der Personen-Klasse hinzufügen, das ist, wo ich die Idee von bekam:

How do I add a attribute to a XmlArray element (XML Serialization)?

49

Markieren Sie Ihre Klasse mit den folgenden Eigenschaften:

[XmlType("Account")] 
[XmlRoot("Account")] 
+11

Ich fand nur die erste notwendig, danke :) – Jeff

+6

Das ist die richtige Antwort. Die anderen Antworten sind nur Workarounds, während dies die eigentliche Lösung ist! – Rhyous

4

Dies ist Minentestcode

using System.Collections.Generic; 
using System.Xml.Serialization; 

namespace TestLoadingMultiXml 
{ 
[XmlRoot([email protected]"main")] 
public class XmlMain 
{ 
    private XmlDataTest data; 

    [XmlElement([email protected]"datalist")] 
    public XmlDataTest Data 
    { 
     get { return data; } 
     set { data = value; } 
    } // public XmlDataTest Data 

    public XmlMain() 
    { 
     data = new XmlDataTest(); 
    } 
} 

[XmlRoot([email protected]"xmldata")] 
public class XmlDataTest 
{ 
    private List<DataDetails> listData; 

    [XmlElement([email protected]"listdata")] 
    public List<DataDetails> Data 
    { 
     get { return listData; } 
     set { listData = value; } 
    } 

    public XmlDataTest() 
    { 
     listData = new List<DataDetails>(); 
     for (int i = 0; i < 10; i++) 
     { 
      DataDetails d = new DataDetails(string.Format("{0}", i)); 
      listData.Add(d); 
     } // for (int i=0; i < 10; i++) 
    } // public XmlDataTest() 
} // class XmlDataTest 

[XmlRoot([email protected]"datadetail")] 
public class DataDetails 
{ 
    private string name; 

    [XmlAttribute([email protected]"name")] 
    public string Name 
    { 
     get 
     { 
      return name; 
     } 
     set { name = value; } 
    } 

    public DataDetails(string _value) 
    { 
     this.name = _value; 
    } // public DataDetails(string _value) 

    public DataDetails() 
    { 
     this.name = ""; 
    } // public DataDetails() 
} // public class DataDetails 
} 

und ausgeführtes Programm

using System; 
using System.IO; 
using System.Windows.Forms; 
using System.Xml.Serialization; 

namespace TestLoadingMultiXml 
{ 
    public partial class Form1 : Form 
    { 
    private XmlMain xt; 
    private string xname = @"x.xml"; 

    public Form1() 
    { 
     InitializeComponent(); 
     this.FormClosing += new FormClosingEventHandler(Form1_FormClosing); 
    } 

    void Form1_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     XmlSerializer x = new XmlSerializer(typeof(XmlMain)); 
     FileStream fs = new FileStream(xname, FileMode.Create); 
     x.Serialize(fs, xt); 
     fs.Close(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     xt = new XmlMain(); 
     xname = Directory.GetCurrentDirectory() + @"\" + xname; 
     if (File.Exists(xname)) 
     { 
      XmlSerializer x = new XmlSerializer(typeof(XmlMain)); 
      FileStream fs = new FileStream(xname, FileMode.Open); 
      xt = (XmlMain)x.Deserialize(fs); 
      fs.Close(); 
     } // if (File.Exists(xname)) 
    } 
} 
} 

Auch ist dies das Ergebnis

<?xml version="1.0"?> 
<main xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <datalist> 
    <listdata name="0" /> 
    <listdata name="1" /> 
    <listdata name="2" /> 
    <listdata name="3" /> 
    <listdata name="4" /> 
    <listdata name="5" /> 
    <listdata name="6" /> 
    <listdata name="7" /> 
    <listdata name="8" /> 
    <listdata name="9" /> 
    </datalist> 
</main> 
2

Es gibt eine andere Alternative. Sie können IXmlSerializable immer in Auflistungen (und jeder anderen Klasse oder Struktur) implementieren, um vollständig zu steuern, wie Elemente geschrieben oder gelesen werden. Viele von Ihnen werden das schon wissen, es ist natürlich nicht bevorzugt, da Sie am Ende vielleicht den "Kessel-Platte" -Code von Hand schreiben, der wirklich eine automatische Logik sein sollte, die mit Attributen spezifiziert wird.

Für Sammlungen, die einem vernünftigen Schema entsprechen müssen, ist es vertretbar. Weil das Framework hier eine harte Einschränkung hat und der Serialisierungscode des vorhandenen Elementtyps nicht dupliziert werden muss, wenn er richtig ausgeführt wird; d. Umschreiben Sie die Serialisierung des Artikels nicht im Sammlungscode, sondern erstellen/rufen Sie einen untergeordneten XmlSerializer in Ihrer ReadXml/WriteXml-Implementierung auf.

Nach der Verwendung von IXmlSerializable ist es nicht möglich, das XmlTypeAttribute anzuwenden (es wird ein Laufzeitfehler ausgegeben, der nur angibt, dass XmlRootAttribute verwendet werden kann). Wenden Sie stattdessen das XmlSchemaProviderAttribute an und geben Sie denselben qualifizierten Namen zurück, den Sie in das XmlTypeAttribute eingegeben hätten. Die alte GetSchema-Methode sollte sowieso null zurückgeben, da sie nur eine reservierte Methode war (laut MSDN), wahrscheinlich weil sie vergessen hat, die Möglichkeit zur Angabe eines anderen Namespaces einzubeziehen. Persönlich verwende ich den gleichen "GetSchema" -Methodenamen in meinem XmlSchemaProviderAttribute, so dass er als vollständige Überschreibung neben der Legacy-Platzhalter-GetSchema-Methode erscheint.

Natürlich wäre die beste Lösung, wenn Microsoft uns erlauben würde, das XmlArrayItemAttribute auf Collection/List-Klassen anzuwenden und diese im XmlSerializer zu verwenden. Standardmäßig verwendet es den Elementnamen des XML-Typs in Sammlungen, was meiner Meinung nach ein Fehler ist, da es der XML-Stammname sein sollte, wenn er angegeben wird, oder der Klassenname, wenn nicht.

Wenn ich Zeit bekomme, komme ich zurück und füge ein Beispiel hinzu. Werfen Sie einen Blick auf die Beispiele für die MSDN-Dokumentation von IXmlSerializable und XmlSchemaProviderAttribute.

http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlschemaproviderattribute(v=vs.110).aspx

0

Ich weiß, es ist eine alte Frage, aber ich lief in das gleiche Problem und keines der scheint Lösungen der OP Frage adresse.So, hier ist meine Lösung (Kommentare in französisch sind, wenn Sie sich fragen):

#region Références 
using System.Collections.Generic; 
using System.Linq; 
using System.Xml; 
using System.Xml.Schema; 
using System.Xml.Serialization; 
#endregion 

namespace XmlSerializationTests 
{ 
    /// <summary> 
    /// Représente une liste qui peut être sérialisée en XML en tant que noeud racine. 
    /// </summary> 
    /// <typeparam name="T">Type des éléments de la liste.</typeparam> 
    public class XmlSerializableList<T> 
     : List<T>, IXmlSerializable 
    { 
     #region Variables 
     private static readonly XmlSerializer _ItemSerializer = new XmlSerializer(typeof(T)); 
     private static readonly string _ItemName; 
     private string _RootName; 
     #endregion 

     #region Méthodes 
     /// <summary> 
     /// Initialisation statique 
     /// </summary> 
     static XmlSerializableList() 
     { 
      _ItemName = (typeof(T).GetCustomAttributes(typeof(XmlRootAttribute), true).FirstOrDefault() as XmlRootAttribute)?.ElementName ?? typeof(T).Name; 
     } 

     /// <summary> 
     /// Obtient le nom racine. 
     /// </summary> 
     protected virtual string RootName 
     { 
      get 
      { 
       if (string.IsNullOrWhiteSpace(_RootName)) _RootName = (GetType().GetCustomAttributes(typeof(XmlRootAttribute), true).FirstOrDefault() as XmlRootAttribute)?.ElementName ?? GetType().Name; 
       return _RootName; 
      } 
     } 

     /// <summary> 
     /// Obtient le nom des éléments. 
     /// </summary> 
     protected virtual string ItemName 
     { 
      get { return _ItemName; } 
     } 

     /// <summary> 
     /// Cette méthode est réservée et ne doit pas être utilisée.Lorsque vous implémentez l'interface IXmlSerializable, vous devez retourner la valeur null (Nothing dans Visual Basic) à partir cette méthode et, si la spécification d'un schéma personnalisé est requise, appliquez à la place <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute"/> à la classe. 
     /// </summary> 
     /// <returns> <see cref="T:System.Xml.Schema.XmlSchema"/> qui décrit la représentation XML de l'objet qui est généré par la méthode <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)"/> et utilisé par la méthode <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)"/>.</returns> 
     public XmlSchema GetSchema() 
     { 
      return null; 
     } 

     /// <summary> 
     /// Génère un objet à partir de sa représentation XML. 
     /// </summary> 
     /// <param name="reader"><see cref="T:System.Xml.XmlReader"/> source à partir de laquelle l'objet est désérialisé.</param> 
     public void ReadXml(XmlReader reader) 
     { 
      if (!reader.IsEmptyElement) 
      { 
       reader.ReadStartElement(); 
       while (reader.NodeType != XmlNodeType.EndElement) 
       { 
        T item = (T) _ItemSerializer.Deserialize(reader); 
        Add(item); 
       } 
       reader.ReadEndElement(); 
      } 
      else reader.ReadStartElement(); 
     } 

     /// <summary> 
     /// Convertit un objet en sa représentation XML. 
     /// </summary> 
     /// <param name="writer"><see cref="T:System.Xml.XmlWriter"/> flux dans lequel l'objet est sérialisé.</param> 
     public void WriteXml(XmlWriter writer) 
     { 
      foreach (var i in this) 
      { 
       XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
       ns.Add("", ""); 
       _ItemSerializer.Serialize(writer, i, ns); 
      } 
     } 
     #endregion 
    } 
} 

Und hier eine Unit-Test-Klasse zu verwenden und Ergebnisse zeigen:

#region Références 
using System.IO; 
using System.Text; 
using System.Xml.Serialization; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
#endregion 

namespace XmlSerializationTests 
{ 
    [TestClass] 
    public class XmlSerializableListTests 
    { 
     public class Person 
     { 
      public string FirstName { get; set; } 
      public string LastName { get; set; } 
      public int Birth { get; set; } 
     } 

     [XmlRoot("color")] 
     public class ColorDefinition 
     { 
      [XmlElement("name")] public string Name { get; set; } 
      [XmlElement("r")] public int Red { get; set; } 
      [XmlElement("g")] public int Green { get; set; } 
      [XmlElement("b")] public int Blue { get; set; } 
     } 

     public class Persons : XmlSerializableList<Person> 
     { 
     } 

     [XmlRoot("colors")] 
     public class ColorList : XmlSerializableList<ColorDefinition> 
     { 
     } 

     private T ReadXml<T>(string text) where T : class 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof (T)); 
      using (StringReader sr = new StringReader(text)) 
      { 
       return serializer.Deserialize(sr) as T; 
      } 
     } 

     private string WriteXml<T>(T data) where T : class 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(T)); 
      StringBuilder sb = new StringBuilder(); 
      using (StringWriter sw = new StringWriter(sb)) 
      { 
       serializer.Serialize(sw, data); 
       return sb.ToString(); 
      } 
     } 

     [TestMethod] 
     public void ReadEmpty() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<XmlSerializableListOfInt32> 
</XmlSerializableListOfInt32>"; 
      XmlSerializableList<int> lst = ReadXml<XmlSerializableList<int>>(xml); 
      Assert.AreEqual(0, lst.Count); 
     } 

     [TestMethod] 
     public void ReadEmpty2() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<XmlSerializableListOfInt32 />"; 
      XmlSerializableList<int> lst = ReadXml<XmlSerializableList<int>>(xml); 
      Assert.AreEqual(0, lst.Count); 
     } 

     [TestMethod] 
     public void ReadSimpleItems() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<XmlSerializableListOfInt32> 
    <int>0</int> 
    <int>52</int> 
    <int>79</int> 
</XmlSerializableListOfInt32>"; 
      XmlSerializableList<int> lst = ReadXml<XmlSerializableList<int>>(xml); 
      Assert.AreEqual(3, lst.Count); 
      Assert.AreEqual(0, lst[0]); 
      Assert.AreEqual(52, lst[1]); 
      Assert.AreEqual(79, lst[2]); 
     } 

     [TestMethod] 
     public void ReadComplexItems() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<XmlSerializableListOfPerson> 
    <Person> 
    <FirstName>Linus</FirstName> 
    <LastName>Torvalds</LastName> 
    <Birth>1969</Birth> 
    </Person> 
    <Person> 
    <FirstName>Bill</FirstName> 
    <LastName>Gates</LastName> 
    <Birth>1955</Birth> 
    </Person> 
    <Person> 
    <FirstName>Steve</FirstName> 
    <LastName>Jobs</LastName> 
    <Birth>1955</Birth> 
    </Person> 
</XmlSerializableListOfPerson>"; 
      XmlSerializableList<Person> lst = ReadXml<XmlSerializableList<Person>>(xml); 
      Assert.AreEqual(3, lst.Count); 
      Assert.AreEqual("Linus", lst[0].FirstName); 
      Assert.AreEqual("Torvalds", lst[0].LastName); 
      Assert.AreEqual(1969, lst[0].Birth); 
      Assert.AreEqual("Bill", lst[1].FirstName); 
      Assert.AreEqual("Gates", lst[1].LastName); 
      Assert.AreEqual(1955, lst[1].Birth); 
      Assert.AreEqual("Steve", lst[2].FirstName); 
      Assert.AreEqual("Jobs", lst[2].LastName); 
      Assert.AreEqual(1955, lst[2].Birth); 
     } 

     [TestMethod] 
     public void ReadInheritedPersons() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<Persons> 
    <Person> 
    <FirstName>Linus</FirstName> 
    <LastName>Torvalds</LastName> 
    <Birth>1969</Birth> 
    </Person> 
    <Person> 
    <FirstName>Bill</FirstName> 
    <LastName>Gates</LastName> 
    <Birth>1955</Birth> 
    </Person> 
    <Person> 
    <FirstName>Steve</FirstName> 
    <LastName>Jobs</LastName> 
    <Birth>1955</Birth> 
    </Person> 
</Persons>"; 
      Persons lst = ReadXml<Persons>(xml); 
      Assert.AreEqual(3, lst.Count); 
      Assert.AreEqual("Linus", lst[0].FirstName); 
      Assert.AreEqual("Torvalds", lst[0].LastName); 
      Assert.AreEqual(1969, lst[0].Birth); 
      Assert.AreEqual("Bill", lst[1].FirstName); 
      Assert.AreEqual("Gates", lst[1].LastName); 
      Assert.AreEqual(1955, lst[1].Birth); 
      Assert.AreEqual("Steve", lst[2].FirstName); 
      Assert.AreEqual("Jobs", lst[2].LastName); 
      Assert.AreEqual(1955, lst[2].Birth); 
     } 

     [TestMethod] 
     public void ReadInheritedColors() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<colors> 
    <color> 
    <name>red</name> 
    <r>255</r> 
    <g>0</g> 
    <b>0</b> 
    </color> 
    <color> 
    <name>green</name> 
    <r>0</r> 
    <g>255</g> 
    <b>0</b> 
    </color> 
    <color> 
    <name>yellow</name> 
    <r>255</r> 
    <g>255</g> 
    <b>0</b> 
    </color> 
</colors>"; 
      ColorList lst = ReadXml<ColorList>(xml); 
      Assert.AreEqual(3, lst.Count); 
      Assert.AreEqual("red", lst[0].Name); 
      Assert.AreEqual(255, lst[0].Red); 
      Assert.AreEqual(0, lst[0].Green); 
      Assert.AreEqual(0, lst[0].Blue); 
      Assert.AreEqual("green", lst[1].Name); 
      Assert.AreEqual(0, lst[1].Red); 
      Assert.AreEqual(255, lst[1].Green); 
      Assert.AreEqual(0, lst[1].Blue); 
      Assert.AreEqual("yellow", lst[2].Name); 
      Assert.AreEqual(255, lst[2].Red); 
      Assert.AreEqual(255, lst[2].Green); 
      Assert.AreEqual(0, lst[2].Blue); 
     } 

     [TestMethod] 
     public void WriteEmpty() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<XmlSerializableListOfInt32 />"; 
      XmlSerializableList<int> lst = new XmlSerializableList<int>(); 
      string result = WriteXml(lst); 
      Assert.AreEqual(xml, result); 
     } 

     [TestMethod] 
     public void WriteSimpleItems() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<XmlSerializableListOfInt32> 
    <int>0</int> 
    <int>52</int> 
    <int>79</int> 
</XmlSerializableListOfInt32>"; 
      XmlSerializableList<int> lst = new XmlSerializableList<int>() {0, 52, 79}; 
      string result = WriteXml(lst); 
      Assert.AreEqual(xml, result); 
     } 

     [TestMethod] 
     public void WriteComplexItems() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<XmlSerializableListOfPerson> 
    <Person> 
    <FirstName>Linus</FirstName> 
    <LastName>Torvalds</LastName> 
    <Birth>1969</Birth> 
    </Person> 
    <Person> 
    <FirstName>Bill</FirstName> 
    <LastName>Gates</LastName> 
    <Birth>1955</Birth> 
    </Person> 
    <Person> 
    <FirstName>Steve</FirstName> 
    <LastName>Jobs</LastName> 
    <Birth>1955</Birth> 
    </Person> 
</XmlSerializableListOfPerson>"; 
      XmlSerializableList<Person> persons = new XmlSerializableList<Person> 
      { 
       new Person {FirstName = "Linus", LastName = "Torvalds", Birth = 1969}, 
       new Person {FirstName = "Bill", LastName = "Gates", Birth = 1955}, 
       new Person {FirstName = "Steve", LastName = "Jobs", Birth = 1955} 
      }; 
      string result = WriteXml(persons); 
      Assert.AreEqual(xml, result); 
     } 

     [TestMethod] 
     public void WriteInheritedPersons() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<Persons> 
    <Person> 
    <FirstName>Linus</FirstName> 
    <LastName>Torvalds</LastName> 
    <Birth>1969</Birth> 
    </Person> 
    <Person> 
    <FirstName>Bill</FirstName> 
    <LastName>Gates</LastName> 
    <Birth>1955</Birth> 
    </Person> 
    <Person> 
    <FirstName>Steve</FirstName> 
    <LastName>Jobs</LastName> 
    <Birth>1955</Birth> 
    </Person> 
</Persons>"; 
      Persons lst = new Persons 
      { 
       new Person {FirstName = "Linus", LastName = "Torvalds", Birth = 1969}, 
       new Person {FirstName = "Bill", LastName = "Gates", Birth = 1955}, 
       new Person {FirstName = "Steve", LastName = "Jobs", Birth = 1955} 
      }; 
      string result = WriteXml(lst); 
      Assert.AreEqual(xml, result); 
     } 

     [TestMethod] 
     public void WriteInheritedColors() 
     { 
      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<colors> 
    <color> 
    <name>red</name> 
    <r>255</r> 
    <g>0</g> 
    <b>0</b> 
    </color> 
    <color> 
    <name>green</name> 
    <r>0</r> 
    <g>255</g> 
    <b>0</b> 
    </color> 
    <color> 
    <name>yellow</name> 
    <r>255</r> 
    <g>255</g> 
    <b>0</b> 
    </color> 
</colors>"; 
      ColorList lst = new ColorList 
      { 
       new ColorDefinition { Name = "red", Red = 255, Green = 0, Blue = 0 }, 
       new ColorDefinition { Name = "green", Red = 0, Green = 255, Blue = 0 }, 
       new ColorDefinition { Name = "yellow", Red = 255, Green = 255, Blue = 0 } 
      }; 
      string result = WriteXml(lst); 
      Assert.AreEqual(xml, result); 
     } 
    } 
}