I have a class that is a list of an abstract class
[XmlInclude(typeof(PostedPayment))]
[XmlInclude(typeof(PostedInvoice))]
[XmlType("VoucherProgress")]
public class PostedJournals : List<APostedJournal>
{
public PostedJournals(IEnumerable<APostedJournal> postedJournals) : base(postedJournals) { }
public PostedJournals() { }
}
开发者_如何学Python
But when I serialize, I end up with
<VoucherProgress>
<APostedJournal p2:type="PostedPayment" xmlns:p2="http://www.w3.org/2001/XMLSchema-instance">
...
</APostedJournal>
</VoucherProgress>
When I want it to name the types, not use the abstract name
<VoucherProgress>
<PostedPayment>
...
</PostedPayment>
</VoucherProgress>
Is there a way to make this work with some attributes?
Here, I got you this far:
< ?xml version="1.0"?>
< MyList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
< MyTypeBase />
< MySubType>something</ MySubType>
< MyTypeBase />
< MyTypeBase />
< MyOtherSubType>something</ MyOtherSubType>
< MyTypeBase />
< MyTypeBase />
< MySubType>something</ MySubType>
< MyTypeBase />
< MyTypeBase />
< MyOtherSubType>something</ MyOtherSubType>
< MyTypeBase />
< MyTypeBase />
< MySubType>something</ MySubType>
< MyTypeBase />
</ MyList >
(I have NO idea how to get XML pasted on this blasted site.
class Program { static void Main(string[] args) { MyList tmp = new MyList();
tmp.Add(new MySubType());
tmp.Add(new MyOtherSubType());
tmp.Add(new MySubType());
tmp.Add(new MyOtherSubType());
tmp.Add(new MySubType());
XmlSerializer xs = new XmlSerializer(typeof(MyList));
MemoryStream ms = new MemoryStream();
xs.Serialize(ms, tmp);
ms.Seek(0, SeekOrigin.Begin);
TextReader tr = new StreamReader(ms);
string xt = tr.ReadToEnd();
}
}
[XmlRoot(ElementName="MyList")]
public class MyList : List<MyTypeBase> { }
[XmlInclude(typeof(MySubType))]
public class MyTypeBase : IXmlSerializable
{
public int ID { get; set; }
protected virtual Type elType { get { return typeof(MyTypeBase); } }
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteEndElement();
writer.WriteStartElement(elType.Name);
writer.WriteValue("something");
writer.WriteEndElement();
writer.WriteStartElement("MyTypeBase");
}
}
public class MySubType : MyTypeBase, IXmlSerializable
{
public string Name { get; set; }
protected override Type elType { get { return typeof(MySubType); } }
}
public class MyOtherSubType : MyTypeBase, IXmlSerializable
{
public string Name { get; set; }
protected override Type elType { get { return typeof(MyOtherSubType); } }
}
The code makes the list you want but with additional MtTypeBase elements which you can figure out on your own. All it does it changes the way the base class is serialized. Each subclass changes the elType to it's own class type so the base class can use it to do it's thing. I already spent a ton of time on this so you can take it form here. Plenty of ways to improve this and make it better and cleaner.
精彩评论