C# 是否可以将 XML 反序列化为 List<T>?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/608110/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to deserialize XML into List<T>?
提问by Daniel Schaffer
Given the following XML:
给定以下 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>
And the following class:
以及以下课程:
public class User {
[XmlElement("id")]
public Int32 Id { get; set; }
[XmlElement("name")]
public String Name { get; set; }
}
Is it possible to use XmlSerializer
to deserialize the xml into a List<User>
? If so, what type of additional attributes will I need to use, or what additional parameters do I need to use to construct the XmlSerializer
instance?
是否可以用于XmlSerializer
将 xml 反序列化为List<User>
? 如果是这样,我需要使用什么类型的附加属性,或者我需要使用哪些附加参数来构造XmlSerializer
实例?
An array ( User[]
) would be acceptable, if a bit less preferable.
数组 ( User[]
) 是可以接受的,如果不太可取的话。
采纳答案by Marc Gravell
You can encapsulatethe list trivially:
您可以简单地封装列表:
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);
}
}
回答by JaredPar
Not sure about List<T> but Arrays are certainly do-able. And a little bit of magic makes it really easy to get to a List again.
不确定 List<T> 但数组肯定是可行的。一点点魔法使再次访问列表变得非常容易。
public class UserHolder {
[XmlElement("list")]
public User[] Users { get; set; }
[XmlIgnore]
public List<User> UserList { get { return new List<User>(Users); } }
}
回答by Coincoin
Yes, it will serialize and deserialize a List<>. Just make sure you use the [XmlArray] attribute if in doubt.
是的,它将序列化和反序列化 List<>。如果有疑问,请确保使用 [XmlArray] 属性。
[Serializable]
public class A
{
[XmlArray]
public List<string> strings;
}
This works with both Serialize() and Deserialize().
这适用于 Serialize() 和 Deserialize()。
回答by Nemo
Yes, it does deserialize to List<>. No need to keep it in an array and wrap/encapsulate it in a list.
是的,它确实反序列化为 List<>。无需将其保存在数组中并将其包装/封装在列表中。
public class UserHolder
{
private List<User> users = null;
public UserHolder()
{
}
[XmlElement("user")]
public List<User> Users
{
get { return users; }
set { users = value; }
}
}
Deserializing code,
反序列化代码,
XmlSerializer xs = new XmlSerializer(typeof(UserHolder));
UserHolder uh = (UserHolder)xs.Deserialize(new StringReader(str));
回答by tudor.iliescu
I think I have found a better way. You don't have to put attributes into your classes. I've made two methods for serialization and deserialization which take generic list as parameter.
我想我找到了更好的方法。您不必将属性放入类中。我已经制作了两种以通用列表作为参数的序列化和反序列化方法。
Take a look (it works for me):
看看(它对我有用):
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;
}
So you can serialize whatever list you want! You don't need to specify the list type every time.
所以你可以序列化你想要的任何列表!您不需要每次都指定列表类型。
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);
回答by PRJ
How about
怎么样
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);
Not particularly fancy but it should work.
不是特别花哨,但它应该工作。
回答by richaux
If you decorate the User
class with the XmlType
to match the required capitalization:
如果您使用 装饰User
类XmlType
以匹配所需的大写:
[XmlType("user")]
public class User
{
...
}
Then the XmlRootAttribute
on the XmlSerializer
ctor can provide the desired root and allow direct reading into List<>:
然后ctorXmlRootAttribute
上的XmlSerializer
可以提供所需的根并允许直接读入 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);
}