XmlRoot
does not seem to work with classes that are contained within a collection. Here are the classes I have defined:
[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; }
}
Here is the code I am using to serialize these objects:
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();
}
The xml after serialization looks like this:
<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>
Notice the "C" in car is not lowercase. What do I need to change to make this happen? If I serialize the Car directly it comes out as I would expectg.
UPDATE: I found another workaround. I am not sure how much I like it but it will work for my case. If I create a custom class (see below) and have CarCollection derive from it the serialization works as I expected.
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);
}
}
}