是否有可能将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);
不是特别花哨,但它应该工作。