É possível desserializar XML em List ?

Dado o seguinte XML:

   1 Joe   2 John   

E a seguinte class:

 public class User { [XmlElement("id")] public Int32 Id { get; set; } [XmlElement("name")] public String Name { get; set; } } 

É possível usar o XmlSerializer para desserializar o xml em uma List ? Em caso afirmativo, que tipo de atributos adicionais eu precisarei usar ou quais parâmetros adicionais eu preciso usar para construir a instância XmlSerializer ?

Uma matriz ( User[] ) seria aceitável, se um pouco menos preferível.

Você pode encapsular a lista trivialmente:

 using System; using System.Collections.Generic; using System.Xml.Serialization; [XmlRoot("user_list")] public class UserList { public UserList() {Items = new List();} [XmlElement("user")] public List Items {get;set;} } public class User { [XmlElement("id")] public Int32 Id { get; set; } [XmlElement("name")] public String Name { get; set; } } static class Program { static void Main() { XmlSerializer ser= new XmlSerializer(typeof(UserList)); UserList list = new UserList(); list.Items.Add(new User { Id = 1, Name = "abc"}); list.Items.Add(new User { Id = 2, Name = "def"}); list.Items.Add(new User { Id = 3, Name = "ghi"}); ser.Serialize(Console.Out, list); } } 

Se você decorar a class User com o XmlType para corresponder à capitalização necessária:

 [XmlType("user")] public class User { ... } 

Em seguida, o XmlRootAttribute no XmlSerializer ctor pode fornecer a raiz desejada e permitir a leitura direta em List <>:

  // eg my test to create a file using (var writer = new FileStream("users.xml", FileMode.Create)) { XmlSerializer ser = new XmlSerializer(typeof(List), new XmlRootAttribute("user_list")); List list = new List(); list.Add(new User { Id = 1, Name = "Joe" }); list.Add(new User { Id = 2, Name = "John" }); list.Add(new User { Id = 3, Name = "June" }); ser.Serialize(writer, list); } 

  // read file List users; using (var reader = new StreamReader("users.xml")) { XmlSerializer deserializer = new XmlSerializer(typeof(List), new XmlRootAttribute("user_list")); users = (List)deserializer.Deserialize(reader); } 

Crédito: baseado na resposta do YK1 .

Acho que encontrei um jeito melhor. Você não precisa colocar atributos em suas aulas. Eu fiz dois methods para serialização e desserialização que levam lista genérica como parâmetro.

Dê uma olhada (funciona para mim):

 private void SerializeParams(XDocument doc, List paramList) { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(paramList.GetType()); System.Xml.XmlWriter writer = doc.CreateWriter(); serializer.Serialize(writer, paramList); writer.Close(); } private List DeserializeParams(XDocument doc) { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(List)); System.Xml.XmlReader reader = doc.CreateReader(); List result = (List)serializer.Deserialize(reader); reader.Close(); return result; } 

Então você pode serializar qualquer lista que você quiser! Você não precisa especificar o tipo de lista todas as vezes.

  List list = new List(); list.Add(new AssemblyBO()); list.Add(new AssemblyBO() { DisplayName = "Try", Identifier = "243242" }); XDocument doc = new XDocument(); SerializeParams(doc, list); List newList = DeserializeParams(doc); 

Sim, irá serializar e desserializar uma lista <>. Apenas certifique-se de usar o atributo [XmlArray] em caso de dúvida.

 [Serializable] public class A { [XmlArray] public List strings; } 

Isso funciona com Serialize () e Deserialize ().

Sim, desserialize para listar <>. Não há necessidade de mantê-lo em uma matriz e envolvê-lo / encapsulá-lo em uma lista.

 public class UserHolder { private List users = null; public UserHolder() { } [XmlElement("user")] public List Users { get { return users; } set { users = value; } } } 

Desserializando código,

 XmlSerializer xs = new XmlSerializer(typeof(UserHolder)); UserHolder uh = (UserHolder)xs.Deserialize(new StringReader(str)); 

Não tenho certeza sobre List , mas os Arrays são certamente habilitados. E um pouco de magia torna muito fácil chegar a uma lista novamente.

 public class UserHolder { [XmlElement("list")] public User[] Users { get; set; } [XmlIgnore] public List UserList { get { return new List(Users); } } } 

E se

 XmlSerializer xs = new XmlSerializer(typeof(user[])); using (Stream ins = File.Open(@"c:\some.xml", FileMode.Open)) foreach (user o in (user[])xs.Deserialize(ins)) userList.Add(o); 

Não é particularmente chique, mas deve funcionar.