Posted in:

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.

Want to learn more about LINQ? Be sure to check out my Pluralsight course LINQ Best Practices.

Comments

Comment by vzdesic

Is xraw variable contain loaded xml document?

Comment by vzdesic

Class behind this object should implement IEnumerable? Is this true?

Comment by Mark H

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

Comment by James Wilson

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!

James Wilson