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);
}
}
}
tribe84 richtige Antwort geschrieben ... – lanicor
Mein Problem war, dass das Array intern markiert wurde – Nick