Given the following 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?
EDIT: An array ( User[]
) would be acceptable, if a bit less preferable as well.
-
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.
public class UserHolder { [XmlElement("list")] public User[] Users { get; set; } [XmlIgnore] public List<User> UserList { get { return new List<User>(Users); } } }
Daniel Schaffer : Is it possible to do without the "holder" class?JaredPar : @Daniel, AFAIK, no. You need to serialize and deserialize into some concrete object type. I do not believe that XML serialization natively supports collection classes as the start of a serialization. I do not 100% know that though. -
Yes, it will serialize and deserialize a List<>. Just make sure you use the [XmlArray] attribute if in doubt.
[Serializable] public class A { [XmlArray] public List<string> strings; }
This works with both Serialize() and Deserialize().
-
You can encapsulate the 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); } }
Jon Kragh : Nice solution with the [XmlElement("user")] to avoid an extra level of elements. Looking at this, I thought for sure that it would have emitted aor node (if you did not have the XmlElement attribute), and then add nodes under that. But I tried it and it did not, thus emitting exactly what the question wanted. -
Yes, it does deserialize to List<>. No need to keep it in an array and wrap/encapsulate it in a 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)xSerializer.Deserialize(new StringReader(str));
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.