Friday 21 March 2008

Selecting Custom Objects from LINQ

I have been teaching myself WPF and LINQ to XML to objects by working on a very simple game for my children helping them to learn their "key words" and do some basic maths.

I have the key words stored in a fairly simple XML structure:

<?xml version="1.0" encoding="utf-8" ?>
<KeyWords>
   <Group Name="Level 1">
     <KeyWord>and</KeyWord>
     <KeyWord>cat</KeyWord>
     <KeyWord>he</KeyWord>
     <KeyWord>I</KeyWord>
...

and a KeyWord class to store them in.

class KeyWord 
{
     public string Word { get; set; }
     public string Group { get; set; }
}

The foreach way of parsing the XML is simple enough:

foreach (XElement group in xraw.Elements("Group")) 
{
     foreach (XElement word in group.Elements("KeyWord"))
     {
         wordsList.Add(new KeyWord() 
             { Word = word.Value, 
               Group = group.Attribute("Name").Value });
     }
}

But I wanted to remove the nested foreach loops and do it in one simple LINQ query. It took me a little while to work out how it was done, but once you know it is very simple:

keyWords = (from keyWord in 
    xraw.Elements("Group").Elements("KeyWord")
    select new KeyWord 
        { Word = keyWord.Value, 
          Group = keyWord.Parent.Attribute("Name").Value });

and that's all there is to it. Remarkably simple.

4 comments:

  1. Is xraw variable contain loaded xml document?

    ReplyDelete
  2. Class behind this object should implement IEnumerable? Is this true?

    ReplyDelete
  3. Hi vzdesic, the code to load xraw is simply:
    var xraw = XElement.Load("KeyWords.xml");

    ReplyDelete
  4. Very nice! I had a feeling it was possible to do something like this but had yet to figure it out or find a solution that didn't involve a foreach loop. This is impressive, thanks for sharing!

    ReplyDelete