将XML WebResponse转换为通用对象

时间:2017-12-18 23:07:11

标签: c# xml linq generics

我需要将XML响应解析为不同的类对象。我有许多不同属性的课程。我知道我可以使用LINQ直接创建对象,如下面的代码:

XElement response = XElement.Parse(xmlValue);
IEnumerable<DTO> result =
    from el in response.Descendants("i")
    select new DTO()
    {
        Object_ID = (int)el.Attribute("Object_ID")
        // Other properties mapped here.
    };

我的XML是以下格式,只有属性值,没有元素值:

<root>
    <i attribute1="value" attribute2="value"... attributex="value"/>
    <i attribute1="value" attribute2="value"... attributex="value"/>
    <i attribute1="value" attribute2="value"... attributex="value"/>
    <i attribute1="value" attribute2="value"... attributex="value"/>
</root>

问题是我有多个DTO,我不想为每个案例编写不同的处理程序,因为有很多不同的属性,每个属性的映射会导致冗余的丑陋代码。

我需要将数据存储在IEnumerable类型中。

这是最有效的方法吗?我应该创建一个返回对象的泛型类型转换方法吗?

编辑:我最终使用XmlSerializer解决了这个问题,并对下面接受的答案进行了一些小的调整。代码如下:

    public static IEnumerable<T> DeserializeXml<T>(XElement response)
    {
        var list = new List<T>();
        foreach (var item in response.Descendants("i"))
        {
            using (var sr = new StringReader(student.ToString()))
            {
                var xRoot = new XmlRootAttribute();
                xRoot.ElementName = "i";
                xRoot.IsNullable = true;
                var serializer = new XmlSerializer(typeof(T), xRoot);
                list.Add((T)serializer.Deserialize(sr));
            }
        }
        return list;
    }

2 个答案:

答案 0 :(得分:1)

我可以为Xml中的每个i标记创建一个属性词典,然后返回一个词典集合。

IEnumerable<Dictionary<string, string>> result =
    from tag in response.Descendants("i")
    select tag.Attributes().Select(a =>
        new { key = a.Name.LocalName, value = a.Value.ToString() })
        .ToDictionary(k => k.key, v => v.value);

答案 1 :(得分:1)

如果你想要更强类型的东西(比字符串的字典),就声明的属性名称和类型而言,你可以创建一个用XmlSerizalizer属性注释的DTO并使用通用的数组反序列化器。

[XmlType("i")]
public class DtoI
{
    [XmlAttribute("Object_ID")]
    public int Id;
    [XmlAttribute("attribute1")]
    public String Attribute1;
    [XmlAttribute("attribute2")]
    public String Attribute2;
    [XmlAttribute("attributex")]
    public Int32 AttributeX;
}


public static T[] DeserializeArray<T>(String xml)
{
    using (var reader = new StringReader(xml))
    {
        var serializer = new XmlSerializer(typeof(T[]), new XmlRootAttribute("root"));
        return (T[])serializer.Deserialize(reader);
    }
}