在C#中使用LINQ读取Xml文件

时间:2010-09-10 05:53:32

标签: c# xml linq

我有一个String

列表
      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”中的项目,value是文件中“Name”的属性值

所以结果就像

   Key(String)            Value(List<String>)

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

现在我正在使用嵌套for循环

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

提前致谢

2 个答案:

答案 0 :(得分:3)

我认为这样做会:

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文件,而不是为列表中的每个元素搜索一次文件。

答案 1 :(得分:1)

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中的每个项目迭代一次元素。如果其他人没有拿出一个解决方案,我会在以后提出另一个解决方案。