Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将XML文件读入字典<;字符串,列表<;字符串>&燃气轮机;使用空字符串表示空元素_C#_Xml_Linq_Dictionary - Fatal编程技术网

C# 如何将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

我有一个xml文件,如:

<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
    )是的…现在我使用的是like
    inti=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()
            );