I think you can do everything you want with just the standard XML serialization attributes, without a custom serializer. See the example below:
public class Container
{
[XmlElement("ElementType1", typeof(ElementType1))]
[XmlElement("ElementType2", typeof(ElementType2))]
public ElementBase[] Elements { get; set; }
}
[XmlInclude(typeof(ElementType1)),XmlInclude(typeof(ElementType2))]
public abstract class ElementBase
{
public string Name { get; set; }
}
public class ElementType1 : ElementBase
{
public int ID1 { get; set; }
}
public class ElementType2 : ElementBase
{
public int ID2 { get; set; }
}
Serializing some test data using the default serializer...
var container = new Container
{
Elements = new ElementBase[] {
new ElementType1 { Name = "first object", ID1 = 999 },
new ElementType2 { Name = "second object", ID2 = 31337 }
}
};
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(Container));
serializer.Serialize(stream, container);
... and you get the following output, which looks like the format you need:
<?xml version="1.0" encoding="utf-8"?>
<Container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ElementType1>
<Name>first object</Name>
<ID1>999</ID1>
</ElementType1>
<ElementType2>
<Name>second object</Name>
<ID2>31337</ID2>
</ElementType2>
</Container>