Convert XML String to List <T> without specifying Element Root in C #
I need to convert XML string to List, the method should be generic. I wrote a method, but it doesn't work as expected.
Scenario: # 1
Model class:
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>
Scenario: # 2
Model class:
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>
I need a general method to convert the above XML to List<Employee>
and List<Person>
.
I used the following code
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[];
}
But I am getting NULL
. Please help me how to deal with this.
I have referenced a lot of code, but they say to specify the Root element as a hardcoded value. But I need a general method.
The signature must be
public static T[] ParseXML<T>(this string @this) where T : class { }
Please help me in this regard.
The root name is the default ArrayOfThing
, not ThingList
, so you'll need to specify a serializer:
var ser = new XmlSerializer(list.GetType(), new XmlRootAttribute("EmployeeList"));
However, you also need to cache and reuse this to prevent assembly memory leaks (only the most basic constructors automatically cache). A read-only static field in a generic type is a good bet, for example:
static class SerializerCache<T> {
public static readonly XmlSerializer Instance = new XmlSerializer(
typeof(List<T>), new XmlRootAttribute(typeof(T).Name + "List"));
}
then use SerializerCache<T>.Instance
insteadnew XmlSerializer
Obviously swap lists and arrays, if you like ...
source to share
I got a response from Marc Gravell - Convert XML String to List <T> without specifying Element Root in C # which was marked Correct.
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;
}
}
}
The main method looks like
public static List<Employee> GetEmployeeList(string xml) {
return xml.ParseXML<Employee>();
}