使用反射将 XML 数组反序列化为列表

Deserialize an XML array into a list using reflection

我想将一个 XML 文档反序列化为一个对象,这是我的对象定义:

public class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<string> Hobbies { get; set; }
}

这是 XML 文件,节点名称匹配 class 属性:

<?xml version="1.0" encoding="UTF-8"?>
<items>
    <item type="dict">
        <FirstName type="str">John</FirstName>
        <LastName type="str">Smith</LastName>
        <Hobbies type="list">
            <item type="str">Reading</item>
            <item type="str">Singing</item>
            <item type="str">Tennis</item>
        </Hobbies>
    </item>
</items>

以下代码曾经有效,我会将 XML 节点(在本例中为 item)传递给函数,代码将使用反射将 属性 与子节点匹配节点并设置 属性 值:

public void DeserializeNode(XmlNode node)
{
    var student = new Student();

    foreach (XmlNode child in node)
    {
        PropertyInfo prop = student.GetType().GetProperty(child.Name);
        prop.SetValue(student, child.InnerText);
    }
}

但是上面的函数不再起作用了(XML 输入已经改变,现在它有一个名为 hobbies 的数组)

以下行抛出异常:

prop.SetValue(student, child.InnerText); // child.InnerText = ReadingSingingTennis

这是因为 child.InnerText 爱好 return ReadingSingingTennis 并且代码试图将 List<string> tp 设置为单个 string.

如何修改此功能才能正确设置兴趣爱好?

问题是在爱好中你有节点。

所以你可以这样试试。

 public static void DeserializeNode(XmlNode node)
    {
        var student = new Student();

        foreach (XmlNode child in node)
        {
            PropertyInfo prop = student.GetType().GetProperty(child.Name);
            if (child.Attributes.GetNamedItem("type").Value == "list")
            {
                var list = Activator.CreateInstance(prop.PropertyType);
                foreach (XmlNode item in child)
                {
                    var methodInfo = list.GetType().GetMethod("Add");
                    methodInfo.Invoke(list, new object[] { item.InnerText });
                }

                prop.SetValue(student, list);
            }
            else
            {
                prop.SetValue(student, child.InnerText);
            }
        }
    }

但是如果你有更复杂的xml你应该使用递归和反射