xml 的 C# 优化到多级节点类型的字典
C# Optimisation for xml to dictionary on multilevel node types
我有一个 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 语句,这是另一个约束条件。
您可以通过使用 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;
}
尝试以下:
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());
}
}
}
我有一个 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 语句,这是另一个约束条件。
您可以通过使用 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;
}
尝试以下:
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());
}
}
}