【问题标题】:how to load XML to a generic list object in c#?如何将 XML 加载到 c# 中的通用列表对象?
【发布时间】:2016-03-23 12:38:22
【问题描述】:

我有一个“School”类,它嵌套了“Student”类,“name”作为“Student”的属性。

public class school
{
    private List<student> mystudents;

    public class student
    {
        private string name;
    }
}

一所学校有很多学生,每个学生都有一个名字。

我有一个 XML 文档:

 <school>
    <student>
        <name>John</name>
    </student>
    <student>
        <name>Jane</name>
    </student>
    <student>
        <name>Jack</name>
    </student>
 </school>

比方说,我创建了一个学校对象并想将此 xml 读入学校对象,我该怎么做? 我已经编写了将 XML 读入对象的工作代码,递归地将值复制到所有属性。我不知道如何为List&lt;T&gt; 即通用列表进行这项工作

下面是我递归读取 XML 到通用对象的代码:

  /*----------------------------------------------------------------
    ' Template to read XML document into a Objects
    '-----------------------------------------------------------------*/
    public static T XmlToObject<T>(string fileName, T obj)
    {

        // read XML
        string xmlString = File.ReadAllText(fileName);
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(xmlString);

        // read the root node
        XmlNode groupsListNode = xmlDocument.GetElementsByTagName(obj.GetType().Name).Item(0);

        // iterate through and copy values
        XmlNodeToListProperties(groupsListNode, obj);

        return obj;
    }

 public static void XmlNodeToProperties( XmlNode listNode, object obj)
    {
        //iterate through properties of object and copy from listNode
        foreach(var prop in obj.GetType().GetProperties())
        {
            if (listNode[prop.Name] != null)
            {
                if (listNode[prop.Name].ChildNodes.Count > 1) // has child-properties
                {
                    // call recursively
                    XmlNodeToProperties(listNode[prop.Name], prop.GetValue(obj, null));
                }
                else // no child properties
                {
                    // get proprty type
                    Type t = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;

                    // convert listNode.FirstChild.value to PropertyType
                    object safeValue = CustomConvert( listNode[prop.Name], t) ;
                    // store in object
                    prop.SetValue(obj, safeValue, null);
                }
            }

我确实想过使用serializers,但问题是每个属性都需要xmlElement("name")。我的几个对象/类来自第三方 API,我无权编辑他们的类文件以插入 `xmlElement("name")。有关修改/更改上述通用模板以适应通用列表的任何建议?

【问题讨论】:

    标签: c# .net xml visual-studio


    【解决方案1】:

    你为什么使用GetElementsByTagName?你知道这实际上得到了给定类型的所有后代吗?

    如果您想“反序列化”一个完整的对象树,您应该从根目录开始并逐步完成它。您需要能够将新实例附加到列表/集合/数组,或 obj 实例中为空的对象属性。

    您说的是第 3 方对象。这就是通常很难做到的地方。根据 API,您需要调用一些工厂、父级上的方法或构造函数。如果是构造函数,如果它需要参数,例如所有者/父级,你会怎么做?

    需要有一个严格的约定/定义,因为它必须如何完成才能使其正常工作。

    【讨论】:

    • 每个 xml 文件都包含需要加载到特定自定义对象类型中的数据。因此,我使用GetElementsByTagName,因为我希望可以读取该自定义对象类型的所有内容。我可以从 3rd 方 API 调用类的构造函数。
    猜你喜欢
    • 2016-09-05
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    相关资源
    最近更新 更多