LINQ to XML – My first steps in the world of LINQ 

Having read Programming Microsoft LINQ last summer and having done nothing with it in the mean time started bothering me especially since every other college I’ve got back at the office has worked with it. So I decided it was time to step up to the proverbial ‘'plate’’ and get some game time with LINQ.

As I’m never content in doing “How to ”- Labs and having nothing to show for it, I’ve decided to build an application I can keep using when I done building it. Hopefully I can keep myself committed for a full series of postings on my progress.

Anyways what is this application I want to build? Well it’s an application which gives me a full listing of all the WII games brought out by Nintendo and in where I can keep track of which games I own.

Seeing this going to be a small application with a very limited need to store data, I opted to use an XML file as my datastore. The traditional way of storing CLR-types to XML is to annotate the object with XML-attributes and serializing the object with an xml serializer. Or one could construct and XML document using a  DOM which is as we know a very painstaking, error prone process.

For my first steps in to the world of LINQ I use LINQ to XML to create my datastore. In my application I created a class named GameData which encapsulates all read and writes to the datastore.

   1: /// <summary>
   2:     /// Data repository
   3:     /// </summary>
   4:     class GameData
   5:     {
   6:         private const string dataStoreFile = @"c:\_TFSWorkspace\WIIGames\data\Game.xml";
   7:         public IList<Game> gameList = new List<Game>();
   8:  
   9:         public GameData() 
  10:         { 
  11:             
  12:         }
  13:         public void Add(Game gameToAdd)
  14:         {
  15:             if (!gameList.Contains(gameToAdd)) 
  16:             {
  17:                 gameList.Add(gameToAdd);
  18:             }
  19:         }
  20:         public void Remove(Game gameToRemove)
  21:         {
  22:  
  23:         }
  24:         /// <summary>
  25:         /// loads internal data structure from disk
  26:         /// </summary>
  27:         public void Load() 
  28:         {
  29:             XDocument doc = XDocument.Load(dataStoreFile);
  30:             gameList = (from games in doc.Descendants("game")
  31:                        select new Game() 
  32:                        {
  33:                            Bestandsnaam = games.Element("bestandsnaam").Value,
  34:                            Regio = games.Element("regio").Value,
  35:                            Release = DateTime.ParseExact(games.Element("releasedatum").Value,"dd-MM-yyyy",null),
  36:                            ReleaseNaam = games.Element("releasenaam").Value,
  37:                            HansNummer = Int32.Parse(games.Element("hansnummer").Value),
  38:                            Naam = games.Element("naam").Value,
  39:                            Nummer = Int32.Parse(games.Attribute("nummer").Value)
  40:                            
  41:                        }).ToList<Game>();
  42:         }
  43:         /// <summary>
  44:         /// Saves internal data structure to disk
  45:         /// </summary>
  46:         public void Persist()
  47:         {
  48:             XDocument doc = new XDocument(
  49:                 new XDeclaration("1.0", "utf-8", "yes"),
  50:                 new XElement("games",
  51:                     from game in gameList
  52:                     select new XElement("game",
  53:                         new XAttribute("nummer", game.Nummer),
  54:                         new XElement("naam",game.Naam),
  55:                         new XElement("hansnummer",game.HansNummer),
  56:                         new XElement("releasenaam",game.ReleaseNaam),
  57:                         new XElement("releasedatum",game.Release.ToString("dd-MM-yyyy")),
  58:                         new XElement("regio",game.Regio),
  59:                         new XElement("bestandsnaam",game.Bestandsnaam)
  60:                         )
  61:                       )
  62:                     );
  63:             doc.Save(dataStoreFile);
  64:         }
  65:     }

If you put your eye on linenumber 46 you’ll see the function Persist() in which an XML document is created by using a“functional construction”. A functional construction has the advantage that is puts the developers focus on the hierarchical structure of an XML document itself as apposed to the object construction and the rules of DOM  when constructing an XML document using one of the traditional forms.

 

Functional construction has been made possible by utilizing nested constructors and  Object Initialization Expressions. As you can see on line 51 through 61 the collection of games gets iterated over and immediately gets assigned to an new XElement  named “game”.

On line 27 you’ll find the function Load() which does the reverse process of reading the XML document from disk and creating an in-memory representation.

Here’s what the XML looks like:

   1: <?xml version="1.0" encoding="utf-8" standalone="yes"?>
   2: <games>
   3:   <game nummer="0">
   4:     <naam>Manhunt 2 (Europe)</naam>
   5:     <hansnummer>0</hansnummer>
   6:     <releasenaam>MANHUNT.2.PAL.Wii.iNTERNAL-DORADO</releasenaam>
   7:     <releasedatum>01-01-0001</releasedatum>
   8:     <regio></regio>
   9:     <bestandsnaam>mnt2_drd</bestandsnaam>
  10:   </game>
  11:   <game nummer="1">
  12:     <naam>Red Steel (USA)</naam>
  13:     <hansnummer>0</hansnummer>
  14:     <releasenaam>Red_Steel_USA_Wii-PARADOX</releasenaam>
  15:     <releasedatum>21-12-2006</releasedatum>
  16:     <regio />
  17:     <bestandsnaam>pdx-red</bestandsnaam>
  18:   </game>
  19: </games>

Well that is all for now hopefully you can put it to good use. Next time my focus will be making my application searchable by utilizing Lucene.Net.

 

Stay Tuned!

Posted on 10-03-2009 by Hans ter Wal
0 Comments  |  Trackback Url  |  Link to this post
Tags:

Links to this post

Comments

Name:
URL:
Email:
Comments:

CAPTCHA Image Validation