C# 如何将XML文件读入字典<;字符串,列表<;字符串>&燃气轮机;使用空字符串表示空元素
我有一个xml文件,如:C# 如何将XML文件读入字典<;字符串,列表<;字符串>&燃气轮机;使用空字符串表示空元素,c#,xml,linq,dictionary,C#,Xml,Linq,Dictionary,我有一个xml文件,如: <root> <RowDetails RowName="A" ColumnSize="1"> <ColumnDetails ColumnName="A1" /> </RowDetails> <RowDetails RowName="B" ColumnSize="2"> <ColumnDetails ColumnName="B1" /> <ColumnDeta
<root>
<RowDetails RowName="A" ColumnSize="1">
<ColumnDetails ColumnName="A1" />
</RowDetails>
<RowDetails RowName="B" ColumnSize="2">
<ColumnDetails ColumnName="B1" />
<ColumnDetails ColumnName="B2" />
</RowDetails>
<RowDetails RowName="C" ColumnSize="3">
<ColumnDetails ColumnName="C1" />
<ColumnDetails ColumnName="C2" />
<ColumnDetails ColumnName="C3" />
</RowDetails>
</root>
现在,词典将包含:
"A" { "A1" }
"B" { "B1", "B2" }
"C" { "C1", "C2", "C3" }
但我的问题是,我需要所有具有相同计数的列表。应为空条目添加空字符串,因此预期结果为:
"A" { "A1", "", "" }
"B" { "B1", "B2", "" }
"C" { "C1", "C2", "C3" }
如何修改LINQ查询
请帮助我使用LINQ完成此操作
提前感谢。假设您希望在创建
MyDict
后将此作为后处理步骤,基本想法是:
以下是一种返回具有所需特征的新词典的方法,无需改变原始集合:
// The required size is the count of the biggest list
var sizeRequired = MyDict.Values.Max(l => l.Count);
// Each string key should map to a key in the new dictionary
// Each List<string> value should map to a new list, padded as necessary.
var paddedDict = MyDict.ToDictionary
(
kvp => kvp.Key,
kvp => kvp.Value
.Concat(Enumerable.Repeat(string.Empty, sizeRequired - kvp.Value.Count))
.ToList()
);
//所需大小是最大列表的计数
var sizeRequired=MyDict.Values.Max(l=>l.Count);
//每个字符串键都应该映射到新字典中的一个键
//每个列表值都应该映射到一个新列表,并根据需要进行填充。
var paddedDict=MyDict.ToDictionary
(
kvp=>kvp.Key,
kvp=>kvp.Value
.Concat(可枚举的.Repeat(string.Empty,sizeRequired-kvp.Value.Count))
托利斯先生()
);
我不确定是否有“在LINQ”的方法。。。我可能也会做你想在C代码中做的事情
但是,这一要求从何而来?是否应该在希望词典中的所有列表大小相同的地方更改代码?您可以在
IEnumerable
上创建一个扩展方法,以填充到最小大小,内联:
public static class IEnumerableExtensions
{
public static IEnumerable<TSource> PadIfFewerThan<TSource>(
this IEnumerable<TSource> items,
int size, TSource padValue = default(TSource))
{
int count = 0;
foreach (var item in items)
{
++count;
yield return item;
}
foreach (var index in Enumerable.Range(count, size - count))
yield return padValue;
}
}
“A”{“A1”、“”、“”}
“B”{“B1”、“B2”和“}
“C”{“C1”、“C2”、“C3”} 如果您必须拥有
词典
,而不是此处返回的词典
,只需将您的.ToList()
放回组合中即可:
var dictionary = doc.Descendants("RowDetails")
.ToDictionary(
x => x.Attribute("RowName").Value,
x => x.Descendants("ColumnDetails")
.Select(y => y.Attribute("ColumnName").Value)
.PadIfFewerThan(3)
.ToList()
);
(+1) . 你能推荐一个LINQ中的方法吗(而不是
Foreach
)是的…现在我使用的是likeinti=XDoc.substands(“RowDetails”).Max(X=>Convert.ToInt32(X.Attribute(“ColumnSize”).Value)代码>MyDict=XDoc.substands(“RowDetails”).ToDictionary(X=>X.Attribute(“RowName”).Value,X=>X.substands(“ColumnDetails”).Select(Y=>Y.Attribute(“ColumnName”).Value.ToDictionary(X=>X.Key,X=>X.Value.Concat(enumable.Repeat(String.Empty,i-X.Value.Count)).ToList())代码>有什么想法可以简化这个查询吗?我不这么认为。我会把它分开;另一个选择(如果可以的话,我个人会选择)是摆脱这种自定义XML序列化,尽可能使用默认的XML序列化程序。我发现XML的“人类可读性/可编辑性”被高估了;)@Pramodh:这里有3种不同的方法重载,实现一种方法重载需要付出代价。我想,如果你能以一种干净(基本上没有bug)的方式让它很快变得通用,为什么不:)@Pramodh:haveabbug。我的代码工作正常,但字符串仍然是null
:)修复了这一点,为了简单起见,将其还原为单个扩展方法。如果您对更通用的扩展方法感兴趣,请查看编辑历史记录。
// The required size is the count of the biggest list
var sizeRequired = MyDict.Values.Max(l => l.Count);
// Each string key should map to a key in the new dictionary
// Each List<string> value should map to a new list, padded as necessary.
var paddedDict = MyDict.ToDictionary
(
kvp => kvp.Key,
kvp => kvp.Value
.Concat(Enumerable.Repeat(string.Empty, sizeRequired - kvp.Value.Count))
.ToList()
);
public static class IEnumerableExtensions
{
public static IEnumerable<TSource> PadIfFewerThan<TSource>(
this IEnumerable<TSource> items,
int size, TSource padValue = default(TSource))
{
int count = 0;
foreach (var item in items)
{
++count;
yield return item;
}
foreach (var index in Enumerable.Range(count, size - count))
yield return padValue;
}
}
var dictionary = doc.Descendants("RowDetails")
.ToDictionary(
x => x.Attribute("RowName").Value,
x => x.Descendants("ColumnDetails")
.Select(y => y.Attribute("ColumnName").Value)
.PadIfFewerThan(3, "")
);
foreach (var entry in dictionary)
Console.WriteLine(@"""{0}"" {{""{1}""}}",
entry.Key,
string.Join(@""",""", entry.Value)
);
var dictionary = doc.Descendants("RowDetails")
.ToDictionary(
x => x.Attribute("RowName").Value,
x => x.Descendants("ColumnDetails")
.Select(y => y.Attribute("ColumnName").Value)
.PadIfFewerThan(3)
.ToList()
);