XmlRoot
ne semble pas fonctionner avec les classes contenues dans une collection. Voici les classes je définis:Xml Sérialisation dans une collection
[XmlRoot("cars")]
public class CarCollection : Collection<Car>
{
}
[XmlRoot("car")]
public class Car
{
[XmlAttribute("make")]
public String Make { get; set; }
[XmlAttribute("model")]
public String Model { get; set; }
}
Voici le code que je utilise pour sérialiser ces objets:
CarCollection cars = new CarCollection();
cars.Add(new Car { Make = "Ford", Model = "Mustang" });
cars.Add(new Car { Make = "Honda", Model = "Accord" });
cars.Add(new Car { Make = "Toyota", Model = "Tundra" });
using (MemoryStream memoryStream = new MemoryStream())
{
XmlSerializer carSerializer = new XmlSerializer(typeof(CarCollection));
carSerializer.Serialize(memoryStream, cars);
memoryStream.Position = 0;
String xml = null;
using (StreamReader reader = new StreamReader(memoryStream))
{
xml = reader.ReadToEnd();
reader.Close();
}
memoryStream.Close();
}
Le xml après sérialisation ressemble à ceci:
<cars xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Car make="Ford" model="Mustang" />
<Car make="Honda" model="Accord" />
<Car make="Toyota" model="Tundra" />
</cars>
Avis le "C" dans la voiture n'est pas en minuscules. Qu'est-ce que je dois changer pour que cela se produise? Si je sérialise la voiture directement il sort comme je l'attendrais.
MISE À JOUR: J'ai trouvé une autre solution de contournement. Je ne suis pas sûr à quel point je l'aime mais ça marchera pour mon cas. Si je crée une classe personnalisée (voir ci-dessous) et que CarCollection en dérive, la sérialisation fonctionne comme prévu.
public class XmlSerializableCollection<T> : Collection<T>, IXmlSerializable
{
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
{
return;
}
XmlSerializer serializer = new XmlSerializer(typeof(T));
while (reader.NodeType != XmlNodeType.EndElement)
{
T t = (T)serializer.Deserialize(reader);
this.Add(t);
}
if (reader.NodeType == XmlNodeType.EndElement)
{
reader.ReadEndElement();
}
}
public void WriteXml(XmlWriter writer)
{
XmlSerializer reqSerializer = new XmlSerializer(typeof(T));
foreach (T t in this.Items)
{
reqSerializer.Serialize(writer, t);
}
}
}
Savez-vous pourquoi la solution de contournement d'insérer une classe XmlSerializableCollection personnalisée provoque le xml que vous voulez être généré pendant la sérialisation? –
jameswelle
Cela fonctionne car je sérialise manuellement les objets enfants et respecte l'attribut XMLRoot sur l'enfant. –