简体   繁体   English

递归/动态地将XML属性添加到单个动态对象中

[英]Recursively / Dynamically add XML attributes into a single Dynamic Object

So i have an XML document that has multiple tiers like this: 所以我有一个具有多个层次的XML文档,如下所示:

<root>
<Client id='1' name='bob'>
     <health id='1'>
          <ex id='2'\>
          <ex id='3' \>
     </health>
</Client>
<Client id='1' name='bob'>
     <health id='1'>
          <ex id='2'\>
          <ex id='3' \>
     </health>
</Client>
</root>

I am trying to recursively go through the XML document and each attribute to an ExpandoObject and add all sub nodes into an ExpandoObject recursively. 我试图递归地遍历XML文档和每个属性到ExpandoObject,然后将所有子节点递归添加到ExpandoObject中。 So the end result of the above xml would have an ExpandoObject with client attributes and also an ExpandoObject inside of it with attributes of health and 2 expandoObjects with their 'ex' attributes in the health ExpandoObject. 因此,以上xml的最终结果将具有一个带有客户端属性的ExpandoObject,以及一个内部具有健康属性的ExpandoObject,以及2个健康状态ExpandoObject中具有'ex'属性的expandoObjects。 So its like putting an XML document inside of a multidimensional Dictionary aka an ExpandoObject. 因此,这就像将XML文档放入多维字典(又称为ExpandoObject)中一样。

I am having a lot of trouble with the recursion its confusing me hardcore and I can't seem to get it working. 我在递归方面遇到了很多麻烦,因为递归使我的核心困惑,我似乎无法正常工作。 Does anyone know how I can traverse like an XDocument recursively and add an ExpandoObject to itself for every sublevel but if its the same depth level add multiple ExpandoObjects to the object above it? 有谁知道我可以像XDocument那样递归遍历并为每个子级别向其自身添加一个ExpandoObject,但是如果其深度相同,则向其上方的对象添加多个ExpandoObjects?

I know this might confuse you since I am also confused but the end object should look something like this: 我知道这可能会使您感到困惑,因为我也很困惑,但是最终对象应该看起来像这样:

Object asd = [Properties of Client] + (ExpandoObject asd2 = [properties of health] + (ExpandoObject asd3 = properties of ex + ExpandoObject asd4 = properties of ex2) 对象asd = [客户端属性] +(ExpandoObject asd2 = [健康属性] +(ExpandoObject asd3 = ex的属性+ ExpandoObject asd4 = ex2的属性)

I found some code that has been working for me so far. 到目前为止,我发现了一些对我有用的代码。

 public static class XmlDocumentExtension
{
    public static dynamic ToObject(this XmlDocument document)
    {
        XmlElement root = document.DocumentElement;
        return ToObject(root, new ExpandoObject());
    }

    private static dynamic ToObject(XmlNode node, ExpandoObject config, int count = 1)
    {
        var parent = config as IDictionary<string, object>;
        foreach (XmlAttribute nodeAttribute in node.Attributes)
        {
            var nodeAttrName = nodeAttribute.Name.ToString();
            parent[nodeAttrName] = nodeAttribute.Value;
        }
        foreach (XmlNode nodeChild in node.ChildNodes)
        {
            if (IsTextOrCDataSection(nodeChild))
            {
                parent["Value"] = nodeChild.Value;
            }
            else
            {
                string nodeChildName = nodeChild.Name.ToString();
                if (parent.ContainsKey(nodeChildName))
                {
                    parent[nodeChildName + "_" + count] = ToObject(nodeChild, new ExpandoObject(), count++);
                }
                else
                {
                    parent[nodeChildName] = ToObject(nodeChild, new ExpandoObject());
                }
            }
        }
        return config;
    }

    private static bool IsTextOrCDataSection(XmlNode node)
    {
        return node.Name == "#text" || node.Name == "#cdata-section";
    }
}

i think looping this will help you (change 'this' to object of a class that you want to set its properties from xml attributes) : 我认为循环执行将对您有帮助(将“ this”更改为要从xml属性设置其属性的类的对象):

public void AddXElementAttributesToThisClass(XElement xe)
        {
            ExpandoObject obj = new ExpandoObject();
            foreach (var attribute in xe.Attributes())
            {
                 (obj as IDictionary<string, object>)[attribute.Name.ToString()] = attribute.Value.Trim();
            }
            var dynamicDictionary = obj as IDictionary<string, object>;
            foreach (var property in this.GetType().GetProperties())
            {
                var propName = property.Name;
                var value = property.GetValue(this, null);
                if (dynamicDictionary.ContainsKey(propName) && value != dynamicDictionary[propName])
                {
                    var foundXmlObj= dynamicDictionary[propName];
                    property.SetValue(this, foundXmlObj);
                }
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM