LINQ offers an API called LINQ to XML, formally known as XLinq, that provides support for working with XML. This API resides in the System.Xml.Linq namespace, and you need to add a reference to the assembly with the same name to be able to use it. If you installed the Orcas March CTP bits, the assembly can be found in folder C:\Windows\Microsoft.NET\Framework\v3.5.20209.
In the namespace you can find classes such as XNode, XElement, XAttribute, XText, etc.
XElement implements an XML element. It has several constructor. The following snippet constructs an empty element called winner.
XElement root = new XElement("winner");
Console.WriteLine(root.ToString());
The output is
< winner />
Overloaded constructor can take additional parameters. If we pass a string:
XElement root = new XElement("winner", "Manchester Utd.");
We get:
< winner >Manchester Utd.< /winner >
We can also pass an Xattribute
XElement root = new XElement("winner", "Manchester Utd.",
new XAttribute("Year", 1999));
Or
XElement root = new XElement("winner", new XAttribute("Year", 1999),
"Manchester Utd.");
In this case the winner element will have an attribute called Year having the value 1999, and the text of the element will be Manchester Utd..
< winner Year="1999" >Manchester Utd.< /winner >
We can nest the all these to make a hierarchy of xml elements:
XElement root = new XElement("winners",
new XElement("winner",
new XElement("Name", "Barcelona"),
new XElement("Country", "Spania"),
new XElement("Year", 2006)
),
new XElement("winner",
new XElement("Name", "Liverpool"),
new XElement("Country", "Anglia"),
new XElement("Year", 2005)
)
);
Of course, the XML elements don’t have to be created like that. They can be dynamically created. One way is using methods like Add, AddFirst, RemoveNodes, etc., methods from the XContainer class.
IEnumerable< Winner > winners = UCL.GetWinners();
XElement root = new XElement("winners");
foreach (Winner w in winners)
{
root.Add(new XElement("winner",
new XElement("Name", w.Name),
new XElement("Country", w.Country),
new XElement("Year", w.Year)));
}
And we can write this to a file with:
Root.Save("winners.xml");
However, LINQ to XML offers a better way to generate XML content.
IEnumerable< Winner > winners = UCL.GetWinners();
XElement root = new XElement("winners",
from w in winners
select new XElement("winner",
new XElement("Name", w.Name),
new XElement("Country", w.Country),
new XElement("Year", w.Year)));
The result in this case is the same as above.
XElements has several overloads for saving its content to a file:
public void Save(string fileName); public void Save(TextWriter textWriter); public void Save(XmlWriter writer); public void Save(string fileName, bool preserveWhitespace); public void Save(TextWriter textWriter, bool preserveWhitespace);
On the other hand, XElement offers several overloaded static methods for loading content from XML files:
public static XElement Load(string uri); public static XElement Load(TextReader textReader); public static XElement Load(XmlReader reader); public static XElement Load(string uri, bool preserveWhitespace); public static XElement Load(TextReader textReader, bool preserveWhitespace); public static XElement Parse(string text); public static XElement Parse(string text, bool preserveWhitespace);
The following code loads the content of the file winners.xml and prints it in the console.
XElement root = XElement.Load("winners.xml");
Console.WriteLine(root.ToString());
Considering that we have in winners.xml the list of UEL winners, we can load the content of this XML file and create Winner objects:
IEnumerable< Winner > winners =
from e in XElement.Load("winners.xml").Elements("winner")
select new Winner
{
Name = (string)e.Element("Name"),
Country = (string)e.Element("Country"),
Year = (int)e.Element("Year")
};
foreach (Winner w in winners)
{
Console.WriteLine("{0} {1}, {2}", w.Year, w.Name, w.Country);
}
XElement.Load() creates an XElement containing all the elements in the file. Elements() returns only the children called winner (in our case all the children elements of the root). After that we project Winners created by accessing the children of element “winner” in the XML file. The output is
2006 Barcelona, Spania 2005 Liverpool, Anglia 2004 FC Porto, Portugalia 2003 AC Milan, Italia 2002 Real Madrid, Spania 2001 Bayern Munchen, Germania 2000 Real Madrid, Spania 1999 Manchester Utd., Anglia 1998 Real Madrid, Spania 1997 Borussia Dortmund, Germania 1996 Juventus, Italia 1995 AFC Ajax, Olanda 1994 AC Milan, Italia 1993 Olympique de Marseille, Franta
Now suppose you want to project only the names of the winners. In this case we could write:
var winners =
from e in XElement.Load("winners.xml").Elements("winner")
select (string)e.Element("Name");
foreach (var w in winners)
{
Console.WriteLine("{0}", w);
}
The ouput of the program is:
Barcelona Liverpool FC Porto AC Milan Real Madrid Bayern Munchen Real Madrid Manchester Utd. Real Madrid Borussia Dortmund Juventus AFC Ajax AC Milan Olympique de Marseille
This output however lists a team multiple times. If we want to have these winners listed only once we could apply the Distinct operator on the result and select the winners only once:
var winners =
from e in XElement.Load("winners.xml").Elements("winner")
select (string)e.Element("Name");
var winnersDistinct = Enumerable.Distinct(winners);
foreach (var w in winnersDistinct)
{
Console.WriteLine("{0}", w);
}
The new output would be
Barcelona Liverpool FC Porto AC Milan Real Madrid Bayern Munchen Manchester Utd. Borussia Dortmund Juventus AFC Ajax Olympique de Marseille










Thanks for sharing, I had been wondering about this and your code really helped.