简体   繁体   English

如何将xml字符串反序列化为一组C#类,而不必只为xml属性声明很多属性?

[英]How to deserialize a xml string to a set of C# classes without having to declare a lot properties just for xml attributes?

I have the xml below and I am wondering how can it be deserialized to a set of classes without having to add tons of fields (to those classes) just for the sake of representing the different xml attributes (and their respective values). 我有下面的xml,我想知道如何才能将它反序列化为一组类,而不必为了表示不同的xml属性(及其各自的值)而添加大量字段(向那些类)。

I thought I could have something which support declarative xml attributes as .NET attributes on top properties that define xml elements. 我以为我可以在定义xml元素的顶级属性上支持声明性xml属性作为.NET属性。

<y:input xmlns:y='http://www.stuff.com/blahblah/42'>
    <y:datas>
        <y:instance yclass='Report' yid="report">
            <language yid='LANG_fr'/>
            <threshold>0.8</threshold>
            <typePeriod>predefinedPeriod</typePeriod>
            <interval>month</interval>
            <valuePeriod>April</valuePeriod>
            <fund yclass="Fund">
                <name>K</name>
                <performance yclass="Performance">
                    <typeValue>percent</typeValue>
                    <value>-0.05</value>
                </performance>
                [... lot of other fields ...]
            </fund>
        </y:instance>
    </y:datas>
</y:input>

You should be able to use ExpandoObject (part of System.Dynamic). 您应该能够使用ExpandoObject(System.Dynamic的一部分)。

I tried a quick solution myself and was able to parse that xml successfully to a dynamic object. 我自己尝试了一种快速解决方案,并且能够成功地将该xml解析为动态对象。

What you need to do is: 您需要做的是:

  1. Parse the string data to XDocument so you have an xml document object. 将字符串数据解析到XDocument,以便您有一个xml文档对象。

    var doc = XDocument.Parse(xmlData);

  2. I then converted the doc to a json string, you don't need to do this but it was the quickest way for me to test if this will work. 然后,我将文档转换为json字符串,您无需执行此操作,但这是我测试此方法是否可行的最快方法。 (For this I needed to add the Newtonsoft.Json NuGet package.) (为此,我需要添加Newtonsoft.Json NuGet包。)

    string jsonText = JsonConvert.SerializeXNode(doc);

  3. Then lastly I deserilzed the object like this: 最后,我像这样对对象进行了反序列化:

    dynamic dyn = JsonConvert.DeserializeObject< ExpandoObject >(jsonText);

I like using xml linq along with a nested dictionary : 我喜欢将xml linq与嵌套字典一起使用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {

            XDocument doc = XDocument.Load(FILENAME);
            XNamespace yNs = doc.Root.GetNamespaceOfPrefix("y");
            Datas data = doc.Descendants(yNs + "datas").Select(x => new Datas() {
                instances = x.Descendants(yNs + "instance").Select(y => new Instance() {
                    instance = (string)y.Attribute("yid"),
                    language = (string)y.Element("language").Attribute("yid"),
                    threshold = (decimal)y.Element("threshold"),
                    typePeriod = (string)y.Element("typePeriod"),
                    interval = (string)y.Element("interval"),
                    valuePeriod = (string)y.Element("valuePeriod"),
                    fund = y.Elements("fund").Select(z => new Fund() {
                        fields  = z.Elements().GroupBy(a => a.Name.LocalName, b => b.Elements()
                            .GroupBy(c => c.Name.LocalName, d => (string)d)
                            .ToDictionary(c => c.Key, d => d.FirstOrDefault()))
                            .ToDictionary(a => a.Key, b => b.FirstOrDefault())
                    }).FirstOrDefault()
                }).ToList()
            }).FirstOrDefault();
        }
    }
    public class Datas
    {
        public List<Instance> instances { get; set; }
    }
    public class Instance
    {
        public string instance { get; set; }
        public string language { get; set; }
        public decimal threshold { get; set; }
        public string typePeriod { get; set; }
        public string interval { get; set; }
        public string valuePeriod { get; set; }
        public Fund fund { get; set; }
     }
    public class Fund
    {
        public Dictionary<string, Dictionary<string,string>> fields { get; set; }
    }
}

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

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