是否有可能将XML反序列化为List <T>?

鉴于以下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> 

和以下class级:

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

是否有可能使用XmlSerializer反序列化到List<User>的XML? 如果是这样,我需要使用什么types的附加属性,或者我需要使用什么额外的参数来构造XmlSerializer实例?

一个数组( User[] )将是可以接受的,如果有点不太好。

你可以简单地封装列表:

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

如果使用XmlType装饰User类以匹配所需的大小写:

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

然后XmlSerializer ctor上的XmlRootAttribute可以提供所需的根,并允许直接读入List <>:

  // eg 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); } 

学分:根据YK1的 答案 。

是的,它会序列化和反序列化一个List <>。 如果有疑问,请确保使用[XmlArray]属性。

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

这与Serialize()和Deserialize()一起工作。

我想我find了一个更好的办法。 您不必将属性放入类中。 我已经提出了两种以generics列表为参数的序列化和反序列化方法。

看看(对我有用):

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

所以你可以序列化你想要的任何列表! 您不需要每次指定列表types。

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

不知道List <T>,但数组肯定是可以的。 有一点魔力使得再次到达列表非常容易。

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

是的,它反序列化为List <>。 不需要将其保存在一个数组中,并将其封装/封装在列表中。

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

反序列化代码,

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

怎么样

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

不是特别花哨,但它应该工作。