다음과 같은 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을 deserialize하는 데 사용할 수 있습니까?List<User>
있습니까? 그렇다면 어떤 유형의 추가 속성을 사용해야합니까, 또는 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);
}
}
답변
필요한 대문자와 일치하도록 User
클래스 를 장식하면 XmlType
:
[XmlType("user")]
public class User
{
...
}
그런 다음 XmlRootAttribute
온 XmlSerializer
ctor에 원하는 루트를 제공하고 목록 <>에 직접 읽기를 허용 할 수 있습니다 :
// 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);
}
답변
예, List <>를 직렬화하고 역 직렬화합니다. 확실하지 않은 경우 [XmlArray] 속성을 사용해야합니다.
[Serializable]
public class A
{
[XmlArray]
public List<string> strings;
}
이것은 Serialize () 및 Deserialize ()와 함께 작동합니다.
답변
더 나은 방법을 찾았다 고 생각합니다. 클래스에 속성을 넣을 필요는 없습니다. 일반 목록을 매개 변수로 사용하는 직렬화 및 직렬화 해제에 대한 두 가지 방법을 만들었습니다.
한번보세요 (그것은 나를 위해 작동합니다) :
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);
답변
예, 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 <T>에 대해서는 확실하지 않지만 배열은 확실히 가능합니다. 그리고 약간의 마술로 인해 목록에 다시 쉽게 도달 할 수 있습니다.
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);
특히 화려하지는 않지만 작동해야합니다.
