Можно ли десериализовать 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>
и следующий класс:
public class User {
[XmlElement("id")]
public Int32 Id { get; set; }
[XmlElement("name")]
public String Name { get; set; }
}
можно использовать XmlSerializer для десериализации xml в List<User> ? Если да, то какие дополнительные атрибуты мне нужно будет использовать, или какие дополнительные параметры мне нужно использовать для построения XmlSerializer экземпляр?
массив ( User[] ) было бы приемлемо, если немного менее предпочтителен.
7 ответов:
вы можете инкапсуляция список тривиально:
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); } }
если вы украсите
UserклассXmlTypeчтобы соответствовать требуемой капитализации:[XmlType("user")] public class User { ... }тут
XmlRootAttributeнаXmlSerializerctor может предоставить нужный корень и разрешить прямое чтение в список:// 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); }
Я думаю, что нашел лучший способ. Вы не должны помещать атрибуты в свои классы. Я сделал два методы для сериализации и десериализации, которые принимают общий список в качестве параметра.
посмотреть (это работает для меня):
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; }таким образом, вы можете сериализовать любой список, который вы хотите! Вам не нужно указывать тип списка каждый раз.
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);
Да, он будет сериализовать и десериализовать список. Просто убедитесь, что вы используете атрибут [XmlArray], если сомневаетесь.
[Serializable] public class A { [XmlArray] public List<string> strings; }это работает как с сериализацией (), так и с десериализацией ().
Да, он десериализуется в 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)xs.Deserialize(new StringReader(str));
Не уверен в List
, но массивы, безусловно, способны. И немного магии делает его действительно легко добраться до списка снова. public class UserHolder { [XmlElement("list")] public User[] Users { get; set; } [XmlIgnore] public List<User> UserList { get { return new List<User>(Users); } } }
как о
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);не особо шикарный, но он должен работать.
Comments