简体   繁体   中英

Reading Xml file using LINQ in C#

I have a list of String

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

And an xml file like

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

i need to read contets of the xml file and add to a dictionary

    Dictionary<String,List<String>> dict

where the dictionary key is the items in the "lst" and value is the attribute value of "Name" from the file

So the result will be like

   Key(String)            Value(List<String>)

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

now i'm using nested for loop for this

Is there any wau to do this using LINQ to XML

Thanks in advance

I think this will do it:

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());

Using a helper method:

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

If you don't mind having an empty list instead of null for items which aren't in the XML file, the second statement can be simplified, with no need for the helper method:

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

Note that I've structured this so that it only needs to go through the XML file once, instead of searching through the file once for each element in the list.

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

This can be made more efficient. I iterate over the elements once for every item in lst . I'll properly come up with another solution later if others don't come up with one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM