serializar read parse objects deserialize deserializar c# serialization xml-serialization xml-deserialization

read - xml to list object c#



¿Es posible deserializar XML en List<T>? (7)

Dado el siguiente XML:

<?xml version="1.0"?> <user_list> <user> <id>1</id> <name>Joe</name> </user> <user> <id>2</id> <name>John</name> </user> </user_list>

Y la siguiente clase:

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

¿Es posible usar XmlSerializer para deserializar el xml en una List<User> ? De ser así, ¿qué tipo de atributos adicionales necesitaré usar o qué parámetros adicionales necesito usar para construir la instancia de XmlSerializer ?

Una matriz ( User[] ) sería aceptable, si es un poco menos preferible.


Creo que he encontrado una mejor manera. No tienes que poner atributos en tus clases. He hecho dos métodos para serialización y deserialización que toman la lista genérica como parámetro.

Echa un vistazo (me funciona):

private void SerializeParams<T>(XDocument doc, List<T> 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<T> DeserializeParams<T>(XDocument doc) { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(List<T>)); System.Xml.XmlReader reader = doc.CreateReader(); List<T> result = (List<T>)serializer.Deserialize(reader); reader.Close(); return result; }

¡Entonces puedes serializar la lista que quieras! No necesita especificar el tipo de lista cada vez.

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


No estoy seguro acerca de la Lista <T> pero las matrices son ciertamente factibles. Y un poco de magia hace que sea muy fácil llegar a una Lista de nuevo.

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


Puede encapsular la lista trivialmente:

using System; using System.Collections.Generic; using System.Xml.Serialization; [XmlRoot("user_list")] public class UserList { public UserList() {Items = new List<User>();} [XmlElement("user")] public List<User> 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); } }


Qué tal si

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);

No es particularmente elegante, pero debería funcionar.


Sí, se deserializa a List <>. No es necesario mantenerlo en una matriz y envolver / encapsularlo en una lista.

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

Código de deserialización

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


Sí, serializará y deserializará una Lista <>. Solo asegúrate de usar el atributo [XmlArray] si tienes dudas.

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

Esto funciona con Serialize () y Deserialize ().


Si decora la clase User con XmlType para que coincida con las mayúsculas necesarias:

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

Entonces XmlRootAttribute en el ctor XmlSerializer puede proporcionar la raíz deseada y permitir la lectura directa en List <>:

// e.g. my test to create a file using (var writer = new FileStream("users.xml", FileMode.Create)) { XmlSerializer ser = new XmlSerializer(typeof(List<User>), new XmlRootAttribute("user_list")); List<User> list = new List<User>(); 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<User> users; using (var reader = new StreamReader("users.xml")) { XmlSerializer deserializer = new XmlSerializer(typeof(List<User>), new XmlRootAttribute("user_list")); users = (List<User>)deserializer.Deserialize(reader); }

Crédito: basado en la answer de YK1 .