【问题标题】:Reading Xml file using LINQ in C#在 C# 中使用 LINQ 读取 Xml 文件
【发布时间】:2010-09-10 05:53:31
【问题描述】:

我有一个字符串列表

      List<String> lst=new List<String>{"A","B","C"}

还有一个类似的xml文件

<Root>
<ChildList>
   <Childs>
      <Child Name="a1" Val="A"/>
      <Child Name="a2" val="A"/>
      <Child Name="b1" val="B"/>
   </Childs>
 </ChildList>
 </Root>

我需要阅读 xml 文件的内容并添加到字典中

    Dictionary<String,List<String>> dict

其中字典键是“lst”中的项目,值是文件中“名称”的属性值

所以结果会是这样的

   Key(String)            Value(List<String>)

   "A"                          "a1","a2"
   "B"                           "b1"
   "C"                           null

现在我为此使用嵌套的 for 循环

是否有任何 wau 使用 LINQ to XML 来做到这一点

提前致谢

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    我认为这样做可以:

    XDocument doc = XDocument.Load("foo.xml");
    ILookup<string, string> lookup = doc.Descendants("Childs")
                                        .First()
                                        .Elements("Child")
                                        .ToLookup(x => (string) x.Attribute("Val"),
                                                  x => (string) x.Attribute("Name"));
    
    var dictionary = lst.ToDictionary(x => x,
                             x => lookup[x].ToList().NullIfEmpty());
    

    使用辅助方法:

    public static List<T> NullIfEmpty<T>(this List<T> list)
    {
        return list.Count == 0 ? null : list;
    }
    

    如果您不介意为不在 XML 文件中的项目提供一个空列表而不是 null,则可以简化第二条语句,而无需辅助方法:

    var dictionary = lst.ToDictionary(x => x, x => lookup[x].ToList());
    

    请注意,我对此进行了结构化,因此它只需要遍历 XML 文件一次,而不是为列表中的每个元素搜索一次文件。

    【讨论】:

    • @Jon Skeet,我认为 ToDictionary 应该是 var dictionary = lookup.ToDictionary(x =&gt; x.Key, x =&gt; lookup[x.Key].ToList());
    • @Jon Skeet:你能解释一下ILookup的用途吗
    • @Chris:不,因为这样您就不会在lst 中看到不在查找中的条目。此外,在这种情况下,您只需执行... = lookup.ToDictionary(x =&gt; x.Key, x =&gt; x.Value.ToList()); 而无需再次查找密钥。
    • @Pramodh:基本上它就像一本字典,但每个键都与多个值相关联。请注意,与普通字典不同,如果您要求查找中不存在的键,它将返回一个空序列。
    • @Jon,对不起,我错过了lst 来自问题中的代码。
    【解决方案2】:
    var xml = @"<Root>
    <ChildList>
       <Childs>
          <Child Name=""a1"" Val=""A""/>
          <Child Name=""a2"" Val=""A""/>
          <Child Name=""b1"" Val=""B""/>
       </Childs>
     </ChildList>
     </Root>";
    
    var lst= new List<String> { "A", "B", "C" };
    var doc = XDocument.Parse(xml);
    
    var dict = (from item in lst
                select new
                {
                    Key = item,
                    Value = (from elem in doc.Root.Element("ChildList").Element("Childs").Elements("Child")
                             where (string)elem.Attribute("Val") == item
                             select (string)elem.Attribute("Name")).ToList()
                }).ToDictionary(i => i.Key, i => i.Value);
    

    这可以提高效率。对于lst 中的每个项目,我都会对元素进行一次迭代。如果其他人没有提出一个解决方案,我稍后会适当地提出另一个解决方案。

    【讨论】:

    • @lasseespeholt:谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多