Note that there are some explanatory texts on larger screens.

plurals
  1. POA type of generic list deserialization class?
    text
    copied!<p>OK, so here's the story so far.</p> <p>I could already deserialize individual objects using <code>XmlSerializer</code>, but deserializing lists was proving to be a real headache. I started out by trying to serialize <code>List&lt;Foo&gt;</code> and the serializer serialized multiple <code>&lt;Foo&gt;</code> XML structures inside a root <code>&lt;ArrayOfFoo&gt;</code> element. That proved to be problematic to deserialize, so it looks like I needed to have defined the 'ArrayOfFoo' element myself. So, I've got a class working that is a 'wrapper' for the list, as shown in this program:</p> <pre><code>using System; using System.IO; using System.Collections.Generic; using System.Xml.Serialization; namespace XmlTester2 { public class Program { static void Main(string[] args) { Console.WriteLine("XML tester..."); string xml = "&lt;ItemList xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"&gt;" + "&lt;Person i:type=\"PersonI2\"&gt;" + "&lt;Field1&gt;field1Val&lt;/Field1&gt;" + "&lt;Field2&gt;field2Val&lt;/Field2&gt;" + "&lt;Field3&gt;field3Val&lt;/Field3&gt;" + "&lt;Field4&gt;field4Val&lt;/Field4&gt;" + "&lt;/Person&gt;" + "&lt;Account i:type=\"AccountI2\"&gt;" + "&lt;Field1&gt;field1Val&lt;/Field1&gt;" + "&lt;Field2&gt;field2Val&lt;/Field2&gt;" + "&lt;Field3&gt;field3Val&lt;/Field3&gt;" + "&lt;Field4&gt;field4Val&lt;/Field4&gt;" + "&lt;/Account&gt;" + "&lt;Person i:type=\"PersonI2\"&gt;" + "&lt;Field1&gt;field1Val&lt;/Field1&gt;" + "&lt;Field2&gt;field2Val&lt;/Field2&gt;" + "&lt;Field3&gt;field3Val&lt;/Field3&gt;" + "&lt;Field4&gt;field4Val&lt;/Field4&gt;" + "&lt;/Person&gt;" + "&lt;/ItemList&gt;"; XmlSerializer ser = new XmlSerializer(typeof(ItemList)); using (var reader = new StringReader(xml)) { ItemList result = (ItemList)ser.Deserialize(reader); } Console.WriteLine("Break here and check 'result' in Quickwatch..."); Console.ReadKey(); } } [XmlRootAttribute(IsNullable = false)] public class ItemList { [XmlElementAttribute("Person")] public List&lt;Person&gt; Persons { get; set; } [XmlElementAttribute("Account")] public List&lt;Account&gt; Accounts { get; set; } } [XmlTypeAttribute(AnonymousType = false, TypeName = "Person", Namespace = "")] [XmlInclude(typeof(PersonI2))] public class Person { public string Field1 { get; set; } public string Field2 { get; set; } public string Field3 { get; set; } } [XmlTypeAttribute(AnonymousType = false, TypeName = "PersonI2", Namespace = "")] public class PersonI2 : Person { public string Field4 { get; set; } } [XmlTypeAttribute(AnonymousType = false, TypeName = "Account", Namespace = "")] [XmlInclude(typeof(AccountI2))] public class Account { public string Field1 { get; set; } public string Field2 { get; set; } public string Field3 { get; set; } } [XmlTypeAttribute(AnonymousType = false, TypeName = "AccountI2", Namespace = "")] public class AccountI2 : Account { public string Field4 { get; set; } } } </code></pre> <p>However, this 'wrapper', <code>ItemList</code>, still has to have manually defined in it all the elements that might be contained (in the example, Person and Account). What would be really ideal would be to have a generic list wrapper class. I know this is a bit hopeful, but would there be a way to do this? I'm thinking of something along these lines (this does not work, but is just to give you the general idea):</p> <pre><code>using System; using System.IO; using System.Collections.Generic; using System.Xml.Serialization; namespace XmlTester3 { public class Program { static void Main(string[] args) { Console.WriteLine("XML tester..."); string xml = "&lt;ItemList xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"&gt;" + "&lt;Person i:type=\"PersonI2\"&gt;" + "&lt;Field1&gt;field1Val&lt;/Field1&gt;" + "&lt;Field2&gt;field2Val&lt;/Field2&gt;" + "&lt;Field3&gt;field3Val&lt;/Field3&gt;" + "&lt;Field4&gt;field4Val&lt;/Field4&gt;" + "&lt;/Person&gt;" + "&lt;Person i:type=\"PersonI2\"&gt;" + "&lt;Field1&gt;field1Val&lt;/Field1&gt;" + "&lt;Field2&gt;field2Val&lt;/Field2&gt;" + "&lt;Field3&gt;field3Val&lt;/Field3&gt;" + "&lt;Field4&gt;field4Val&lt;/Field4&gt;" + "&lt;/Person&gt;" + "&lt;/ItemList&gt;"; XmlSerializer ser = new XmlSerializer(typeof(ItemList&lt;Person&gt;)); using (var reader = new StringReader(xml)) { ItemList&lt;Person&gt; result = (ItemList&lt;Person&gt;)ser.Deserialize(reader); } Console.WriteLine("Break here and check 'result' in Quickwatch..."); Console.ReadKey(); } } [XmlRootAttribute(IsNullable = false)] [XmlInclude(typeof(Person))] [XmlInclude(typeof(PersonI2))] [XmlInclude(typeof(Account))] [XmlInclude(typeof(AccountI2))] public class ItemList&lt;T&gt; { [XmlElementAttribute] public List&lt;T&gt; Items { get; set; } } [XmlTypeAttribute(AnonymousType = false, TypeName = "Person", Namespace = "")] [XmlInclude(typeof(PersonI2))] public class Person { public string Field1 { get; set; } public string Field2 { get; set; } public string Field3 { get; set; } } [XmlTypeAttribute(AnonymousType = false, TypeName = "PersonI2", Namespace = "")] public class PersonI2 : Person { public string Field4 { get; set; } } [XmlTypeAttribute(AnonymousType = false, TypeName = "Account", Namespace = "")] [XmlInclude(typeof(AccountI2))] public class Account { public string Field1 { get; set; } public string Field2 { get; set; } public string Field3 { get; set; } } [XmlTypeAttribute(AnonymousType = false, TypeName = "AccountI2", Namespace = "")] public class AccountI2 : Account { public string Field4 { get; set; } } } </code></pre> <p>So, the XML structures passed inside the <code>ItemList</code> would only be able to be of one type, say <code>Person</code> in this example, and I could define an <code>ItemList&lt;Person&gt;</code> that would allow me to deserialize a list containing multiple Person objects? Any ideas? If necessary, I wouldn't mind having to tag the <code>ItemList</code> class with an <code>[XmlInclude...]</code> for every type that <code>ItemList</code> might contain a collection of.</p> <p>I'm guessing this is possible, I just haven't figured out quite how? :-) Or is the default XmlSerializer too fussy?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload