将 XML 字符串转换为列表 <T> 而无需在 C# 中指定元素根

Convert XML string to List<T> without specifiying Element Root in C#

我需要将XML字符串转换成List,方法应该是通用的。我写了一个方法,但它没有按预期执行。

场景:#1

型号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>

场景:#2

型号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>

我需要一种通用方法将上面所说的 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 { }

请在这方面帮助我。

默认根名称是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

如果你愿意,显然可以交换列表和数组...

我从 Marc Gravell - 中得出答案,我被标记为正确。

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

Main 方法看起来像

public static List<Employee> GetEmployeeList(string xml) {
    return xml.ParseXML<Employee>();
}