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.

+3


source to share


2 answers


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 ...

+2


source


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>();
}

      

0


source







All Articles