代码之家  ›  专栏  ›  技术社区  ›  Thorin Oakenshield

使用C中的LINQ读取XML文件#

  •  2
  • Thorin Oakenshield  · 技术社区  · 14 年前

    我有一串绳子

          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
    

    其中dictionary键是“lst”中的项,value是文件中“name”的属性值

    所以结果是

       Key(String)            Value(List<String>)
    
       "A"                          "a1","a2"
       "B"                           "b1"
       "C"                           null
    

    现在我使用嵌套for循环

    有没有任何wau可以使用linq-to-xml来完成这项工作?

    提前谢谢

    2 回复  |  直到 14 年前
        1
  •  3
  •   Jon Skeet    14 年前

    我认为这样可以做到:

    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;
    }
    

    如果你不介意用空名单代替 null 对于不在XML文件中的项,可以简化第二条语句,而不需要helper方法:

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

    请注意,我已经对它进行了结构化,这样它只需要遍历XML文件一次,而不需要针对列表中的每个元素搜索该文件一次。

        2
  •  1
  •   Lasse Espeholt    14 年前
    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 . 如果其他人不提出解决方案,我稍后会适当地提出另一个解决方案。