XML the LINQ way
March 11th, 2008
In former posts I often wrote something about LINQ (Language Integrated Query, pronounced “link”) especially when writing about advantages of .NET 3.0.
Today I’d like to give you some really usefull snippets you can use with LINQ when accessing an xml file.
First of all I’ve got to show you the xml file I refer to. It’s just a small document that holds some information about music albums.
<?xml version="1.0" encoding="utf-8" ?> <Albums> <Album> <Artist>Black Sabbath</Artist> <Title>Seventh Star</Title> <Date>2/20/1986</Date> </Album> <Album> <Artist>Judas Priest</Artist> <Title>Jugulator</Title> <Date>3/24/1997</Date> </Album> </Albums>
Reading xml with LINQ can be archieved in the twinkling of an eye.
At first I create some anonymous objects with the properties, Artist, Title, and Date.
XDocument xmlDoc = XDocument.Load("albums.xml"); var albums = from album in xmlDoc.Descendants("Album") select new { Artist = tutorial.Element("Artist").Value, Title = tutorial.Element("Title").Value, Date = tutorial.Element("Date").Value, };
The result (albums) is an IEnumerable collection filled with anonymous objects. It can simply be accessed that way:
foreach(var album in albums) { MessageBox.Show(album.Title.ToString()); MessageBox.Show(album.Date.Subtract(DateTime.Now()).ToString().Format ("Y")); }
For not using anonymous types all the time a better solution is to create a typed list.
List<artist> albums = (from album in xmlDoc.Descendants("Album") select new album { Artist = album.Element("Artist").Value, Title = album.Element("Title").Value, Date = DateTime.Parse(album.Element("Date").Value), }).ToList<album>();
This is pretty clear and can be extend easily.
I also would be possible to constrict the select. If the list should just contain every album with artist’s name being something “black” just type:
List<artist> albums = (from album in xmlDoc.Descendants("Album") where artist.Element("Artist").Value.Contains("Black") select new album { ... }).ToList<album>();
Also distinct, group by, order by and some others operations can be done that way.
To filter the result you can design really complex statements using LINQ.
Creation of an xml file is easy as well. The XDocument and XElement types have a load and a parse method for creating.
The first thing to do is creating a document:
XDocument doc = new XDocument( new XDeclaration("1.0", "utf-8", "yes"), new XComment("All my albums"), //... new xElements )
This is an anonymously typed data structure:
var albums = new[] { new {Artist = "Iron Maiden", Title = "Flight Of Icarus", ID = 3}, new {Artist = "Iron Maiden", Title = "Running Free", ID = 1}, new {Artist = "In Flames", Title = "The Mirror's Truth", ID = 4}, };
When creating the xml out of this, it will be additionally done with proper order (notice that the ID is not in proper sequence). For better demonstration how the data can be filtered I, to simplify matters, added an identification number to each album.
XElement albums = new XElement("albums", from a in albums orderby a.ID //descending select new XElement("Album", new XElement("Artist", a.Artist), new XElement("Title", a.Title), new XAttribute("ID", a.ID) ) );
Notice the difference between XElement and XAttribute:
Element:
<Artist>Iron Maiden</Artist>
Attribute:
<ID = "2"></ID>
or
<ID = "2" />When you’d rather use elements and when using attributes is recommented is described here:
[IBM] Principles of XML design: When to use elements versus attributes
At least you shouldn’t forget to save the file to streams.
doc.Save(@"C:\albums.xml");
I don’t wanted to tell you all about LINQ, it’s more likely to show how incredibly powerful LINQ is. This covers even a small portion of it. LINQ can be used for databases just as easily as it was used here on XML. As you can see, the LINQ project is extremely ambitious and this blog entry has just scratched the surface.






[…] As you know you can query with LINQ lots of different sourcse. It’s possible to query, project and filter data in arrays, enumerable classes, XML (XLINQ), relational database, and third party data sources. Last year I among others wrote something about LINQ & XML. […]
Pingback by Kai’s Blog » LINQ to Amazon — July 1, 2009 @ 3:55 pm