【问题标题】:C# Optimisation for xml to dictionary on multilevel node typesC# 优化 xml 到多级节点类型上的字典
【发布时间】:2020-02-22 18:45:24
【问题描述】:

我有一个 xml 类型:

<?xml version="1.0" encoding="UTF-8" ?>
<root>
  <set1>
    <a>
      <value>False</value>
      <defaultValue>False</defaultValue>
    </a>
    <b>
      <value>False</value>
      <defaultValue>False</defaultValue>
    </b>
  </set1>
  <set2>
     <c>
      <value>False</value>
      <defaultValue>False</defaultValue>
    </c>
  </set2>
</root>

现在我尝试使用以下代码将其转换为字典:

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

namespace testxml
{
    struct ConfigFileElements
    {
        public string value;
        public string defaultValue;
    }
    class xmltestread
    {
        public static Dictionary<string, Dictionary<string, ConfigFileElements>>
            ReadConfigXml(XDocument configFile)
        {
            var dict = new Dictionary<string, Dictionary<string, ConfigFileElements>>();

            if (configFile.Root != null)
            {
                foreach (var element in configFile.Root.Elements())
                {
                    var list = new Dictionary<string, ConfigFileElements>();
                    foreach (var child in element.Elements())
                    {
                        var elementvalues = new ConfigFileElements();
                        foreach (var node in child.Elements())
                        {
                            if (node.Name.ToString().Equals("value"))
                            {
                                elementvalues.value = node.Value;
                            }
                            else if (node.Name.ToString().Equals("defaultValue"))
                            {
                                elementvalues.defaultValue = node.Value;
                            }
                        }
                        list.Add(child.Name.ToString(), elementvalues);
                    }
                    dict.Add(element.Name.ToString(), list);
                }
            }
            return dict;
        }
    }
}

这里的问题是我必须迭代三个循环来构建我的字典,.net 中是否还有其他功能可以使代码清晰且看起来不错。

如 linq to xml 或 xml 中的任何其他类型的内置库,用于执行此类复杂操作

我还会添加更多标签,例如最小/最大值,这些标签会在现有条件中添加一些其他 if else 语句,这是另一个约束。

【问题讨论】:

    标签: c# xml dictionary linq-to-xml


    【解决方案1】:

    您可以通过使用Xml.Linq 和本地函数来解析每个set 项目并按名称获取子xml 元素,从而稍微简化您的代码

    var doc = XDocument.Parse(xml);
    
    var dict = new Dictionary<string, Dictionary<string, ConfigFileElements>>();
    foreach (var set in doc.Root.Elements())
    {
        dict.Add(set.Name.ToString(), ParseSet(set));
    }
    
    Dictionary<string, ConfigFileElements> ParseSet(XElement set)
    {
        var dict = new Dictionary<string, ConfigFileElements>();
        foreach (var element in set.Elements())
        {
            var config = new ConfigFileElements()
            {
                value = element.Elements(nameof(ConfigFileElements.value)?.FirstOrDefault()?.Value,
                //parse min/max on the same way
                defaultValue = element.Elements(nameof(ConfigFileElements.defaultvalue))?.FirstOrDefault()?.Value
            };
    
            dict.Add(element.Name.ToString(), config);
        }
    
        return dict;
    }
    

    【讨论】:

    • 看起来不错,但是假设我添加最大值和最小值,如下所示,那么在这种情况下,我将拥有更多节点 --- FalseFalse FalseFalse
    • 我认为我应该使用 element.NextNode ?
    • @KeshavRaghav 您可以使用element.Elements("value")?.FirstOrDefault() 获取任何名称的子元素,然后获取其值,我已经更新了答案
    【解决方案2】:

    尝试关注:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleAppliation157
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
    
                Dictionary<string, List<List<string>>> dict = doc.Root.Elements()
                    .GroupBy(x => x.Name.LocalName.ToUpper(), y => y.Elements().SelectMany(a => 
                        a.Elements().Select(b => new List<string> { a.Name.LocalName, b.Name.LocalName, (string)b })).ToList()).ToList()
                    .ToDictionary(x => x.Key, y => y.FirstOrDefault());
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      相关资源
      最近更新 更多