将XML转换为动态C#对象


69

我已使用以下C#代码使用JSON.Net框架将JSON数据字符串转换为动态对象:

// Creates a dynamic .Net object representing the JSON data
var ProductDB = JsonConvert.DeserializeObject<dynamic>(JsonData);

转换后,我可以使用如下代码直接访问元素:

// Variables to be used
string ProductID;
string ProductType;
int ProductQty;

// Loop through each of the products
foreach (dynamic product in ProductDB.products)
{
    ProductID = product.id;
    ProductType = product.type;
    ProductQty = product.qty;
}

使用XML数据有与此类似的东西吗?我可以使用JSON.net将我的XML转换为JSON,然后重新使用上面的代码,但这感觉像是在作弊。

谢谢。


Answers:


125
XDocument doc = XDocument.Parse(xmlData); //or XDocument.Load(path)
string jsonText = JsonConvert.SerializeXNode(doc);
dynamic dyn = JsonConvert.DeserializeObject<ExpandoObject>(jsonText);

我认为“作弊”是答案-xml解决方案非常长:)


1
这是最快的解决方案,我喜欢!
dariusc

那真是太棒了
Magnus

2
那很棒!但是,您将如何访问属性?例如,解析.nuspec文件后,我应该能够导航至以下内容,nuspec.package.dependencies.dependency.@version@version无法识别。
安东·乔治厄夫,

这怎么作弊?
Kehlan Krumme '19

1
Anton,属性以“ @”为前缀。另请参阅newtonsoft.com/json/help/html/ConvertingJSONandXML.htm。我通常将ExpandoObject转换为Dictionary。可通过该字典使用'@ <attributename>'键访问该属性。
David Urting,

6

对于将来的访问者,ITDevSpace的另一种选择不包括带有子元素的属性。

public class XmlWrapper
{
    public static dynamic Convert(XElement parent)
    {
        dynamic output = new ExpandoObject();

        output.Name = parent.Name.LocalName;
        output.Value = parent.Value;

        output.HasAttributes = parent.HasAttributes;
        if (parent.HasAttributes)
        {
            output.Attributes = new List<KeyValuePair<string, string>>();
            foreach (XAttribute attr in parent.Attributes())
            {
                KeyValuePair<string, string> temp = new KeyValuePair<string, string>(attr.Name.LocalName, attr.Value);
                output.Attributes.Add(temp);
            }
        }

        output.HasElements = parent.HasElements;
        if (parent.HasElements)
        {
            output.Elements = new List<dynamic>();
            foreach (XElement element in parent.Elements())
            {
                dynamic temp = Convert(element);
                output.Elements.Add(temp);
            }
        }

        return output;
    }
}

以及如何使用呢?
杰克·加斯顿

4

Cinchoo ETL-可用于将xml解析为动态对象的开源库

using (var p = ChoXmlReader.LoadText(xml).WithXPath("/"))
{
    foreach (dynamic rec in p)
        Console.WriteLine(rec.Dump());
}

查阅CodeProject文章以获取其他帮助。

免责声明:我是这个图书馆的作者。


2

从@FSX的答案,我已经成功使用了“将XML解析为C#中的动态对象”的解决方案:

public class XmlToDynamic
{
    public static void Parse(dynamic parent, XElement node)
    {
        if (node.HasElements)
        {
            if (node.Elements(node.Elements().First().Name.LocalName).Count() > 1)
            {
                //list
                var item = new ExpandoObject();
                var list = new List<dynamic>();
                foreach (var element in node.Elements())
                {                        
                    Parse(list, element);                        
                }

                AddProperty(item, node.Elements().First().Name.LocalName, list);
                AddProperty(parent, node.Name.ToString(), item);
            }
            else
            {
                var item = new ExpandoObject();

                foreach (var attribute in node.Attributes())
                {
                    AddProperty(item, attribute.Name.ToString(), attribute.Value.Trim());
                }

                //element
                foreach (var element in node.Elements())
                {
                    Parse(item, element);
                }

                AddProperty(parent, node.Name.ToString(), item);
            }
        }
        else
        {
            AddProperty(parent, node.Name.ToString(), node.Value.Trim());
        }
    }

    private static void AddProperty(dynamic parent, string name, object value)
    {
        if (parent is List<dynamic>)
        {
            (parent as List<dynamic>).Add(value);
        }
        else
        {
            (parent as IDictionary<String, object>)[name] = value;
        }
    }
}

我已经用过了 它在动态对象内部提供动态名称和值时效果很好。
罗杰里奥·席尔瓦
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.