C# Оптимизация для xml для словаря на многоуровневых типах узлов - PullRequest
1 голос
/ 22 февраля 2020

У меня есть 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 для выполнения этого типа сложных операций

также я бы добавил больше тегов, таких как значение min / max, и они добавили бы пару других операторов if else к существующим условиям, что является еще одним ограничением.

Ответы [ 2 ]

1 голос
/ 22 февраля 2020

Вы можете немного упростить свой код, используя 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;
}
0 голосов
/ 23 февраля 2020

Попробуйте следующее:

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());
        }
    }
}
...