我需要将XML字符串转换为List,该方法应该是通用的。我写了一个方法,但它没有按预期执行。
场景:#1
模特课程:
public class Employee {
public int EmpId { get; set; }
public string Name { get; set; }
}
XML:
<EmployeeList
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Employee>
<EmpId>1</EmpId>
<Name>Emma</Name>
</Employee>
<Employee>
<EmpId>2</EmpId>
<Name>Watson</Name>
</Employee>
</EmployeeList>
情景:#2
模特课程:
public class Person {
public int PersonId { get; set; }
public string Name { get; set; }
}
XML:
<PersonList
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Person>
<PersonId>1</EmpId>
<Name>Emma</Name>
</Person>
<Person>
<PersonId>2</EmpId>
<Name>Watson</Name>
</Person>
</PersonList>
我需要一种通用方法将上述XML转换为List<Employee>
和List<Person>
。
我使用了以下代码
public static T[] ParseXML<T>(this string @this) where T : class {
var reader = XmlReader.Create(@this.Trim().ToStream(),new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
return new XmlSerializer(typeof(T[])).Deserialize(reader) as T[];
}
但我得到了NULL
。请帮我解决这个问题。
我引用了大量代码但他们告诉将Root元素指定为硬编码值。但我需要一种通用的方法。
签名应为
public static T[] ParseXML<T>(this string @this) where T : class { }
请在这方面帮助我。
答案 0 :(得分:2)
默认根名称是ArrayOfThing
,而不是ThingList
,因此您需要告诉序列化程序:
var ser = new XmlSerializer(list.GetType(), new XmlRootAttribute("EmployeeList"));
但是,您还需要缓存并重新使用它来防止程序集内存泄漏(只有最基本的构造函数自动缓存)。泛型类型上的静态只读字段是一个不错的选择,例如:
static class SerializerCache<T> {
public static readonly XmlSerializer Instance = new XmlSerializer(
typeof(List<T>), new XmlRootAttribute(typeof(T).Name + "List"));
}
然后使用SerializerCache<T>.Instance
代替new XmlSerializer
如果你愿意,显然可以交换列表和数组......
答案 1 :(得分:0)
我从Marc Gravell - Convert XML string to List<T> without specifiying Element Root in C#得出答案,我将其标记为正确。
public static class SerializerCache<T> {
public static readonly XmlSerializer Instance = new XmlSerializer(
typeof(List<T>), new XmlRootAttribute(typeof(T).Name + "List"));
}
public static class XMLHelper {
public static List<T> ParseXML<T>(this string @this) where T : class {
XmlSerializer serializer = SerializerCache<T>.Instance;
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(@this));
if(!string.IsNullorEmpty(@this) && (serializer != null) && (memStream != null)) {
return serializer.Deserialize(memStream) as List<T>;
}
else {
return null;
}
}
}
主要方法看起来像
public static List<Employee> GetEmployeeList(string xml) {
return xml.ParseXML<Employee>();
}