| Introduction
With .NET 3.0 just around the corner, the Language Integrated Query (LINQ) should be hitting the streets in at least some form. There are two distinct flavours of this langauge enhancement to the .NET Framework. Data LINQ (DLINQ) has been designed to allow SQL like syntax in code to handle relational data and XML LINQ (XLINQ) has been designed to handle XML data in a more natural and intuitive manner than currently available. This short article is based on a 'Nugget' shown at the Birmimgham NxtGenUg Meeting in July.
Creating XML with System.Xml.XmlDocument
Currently, if we want to create some XML in code we have a number of options available to us. We can use the System.Xml.XmlDocument type which is essentially Microsoft's implementation of the XML Document Object Model (DOM). We can also use the System.Xml.XmlTextWriter which is a stream-based writer and allows for fast write-only construction of XML. The latter has advantages of speed, but the former has advantages of being able to manuipulate any part of the XML document. Lets just look at the XmlDocument in this article. Lets say we want to produce the XML shown in Figure 1:
<contacts>
<contact>
<name>Richard Costall</name>
<phone type="work">01234 567890</phone>
</contact>
<contact>
<name>John Price</name>
<phone type="work">02345 678901</phone>
</contact>
</contacts>
Figure 1 – Some sample XML
private XmlDocument CreateXMLFromDOM()
{
XmlDocument doc = new XmlDocument();
XmlElement contacts = doc.CreateElement("contacts");
doc.AppendChild(contacts);
XmlElement contact = doc.CreateElement("contact");
contacts.AppendChild(contact);
XmlElement name = doc.CreateElement("name");
name.InnerText = "Richard Costall";
contact.AppendChild(name);
XmlElement phone = doc.CreateElement("phone");
phone.SetAttribute("type","work");
doc.PreserveWhitespace=true;
phone.InnerText = "01234 678901";
contact.AppendChild(phone);
contact = doc.CreateElement("contact");
contacts.AppendChild(contact);
name = doc.CreateElement("name");
name.InnerText = "John Price";
contact.AppendChild(name);
phone = doc.CreateElement("phone");
phone.SetAttribute("type","work");
doc.PreserveWhitespace=true;
phone.InnerText = "02345 678901";
contact.AppendChild(phone);
return doc;
}
Figure 2 – Creating the sample XML using the System.Xml.XmlDocument
The creation of the XML depends upon the existance of the XmlDocument, that is the document as a whole. There is no way to easily create a 'fragment' and to be honest that's what most of us deal with when we deal with XML, little pieces of the stuff!.
Creating XML with XLINQ Syntax
Figure 3 shows how to create the same XML using XLINQ. You can see that there is no reliance on a 'document', fragments of XML can be easily created. You can still access the 'document' if you want to, but the XLINQ is very much more flexible in what it deems valid XML.
private XElement CreateXMLFromLINQ()
{
XElement contacts =
new XElement("contacts",
new XElement("contact",
new XElement("name","Richard Costall"),
new XElement("phone","01234 5678901", new XAttribute("type","work"))
),
new XElement("contact",
new XElement("name","John Price"),
new XElement("phone","02345 678901", new XAttribute("type","work"))
),
);
return contacts;
}
Figure 3 – Creating the sample XML using XLINQ
As you can see with a little work with the TAB key you can even make it look a little bit like XML, and having written it myself, I have to say it was very easy to do an quite intuitive. The number of lines of code is much reduced and a basic benchmarking test using the Stopwatch class shows that it runs about 40% faster than the DOM method, not bad for CTP code versus Live code ...
Querying XML with System.Xml.XmlDocument
Just creating XML is not much use, we need to be able to do something with it and one of the most useful things is querying it with XPATH. Figure 4 shows how we might do this using the XML DOM method with the System.Xml.XmlDocument type.
private void QueryXMLFromDOM()
{
XmlDocument doc = new XmlDocument();
doc.Load(@"C:\xmldom.xml");
XmlNodeList nodes = doc.SelectNodes(@"contacts/contact/name");
foreach (XmlNode node in nodes)
{
// Do some stuff;
}
}
Figure 4 – Querying sample XML using XML DOM
This is fairly straightfoward, but it does rely on you knowing XPATH (not a bad thing). Figure 5 is the XLINQ version of the same query:
private void QueryXMLFromLINQ()
{
XElement contacts = XElement.Load(@"C:\xlinq.xml");
foreach (XElement name in contacts.Elements("contact").Elements("name"))
{
// Do some stuff;
}
}
Figure 5 – Querying sample XML using XLINQ
No XPATH in sight, and again less code. I quite like this syntax and in fact we have an object container at Ridgian which exhibits similar behaviour, so it is not too unfamiliar to me. What do you think?
Summary
XLINQ should be part of .NET 3.0 language features and does seem to offer good performance and a simpler more intuitive coding style when working with XML. I'd be interested to see what you think about it all. The sample code used in this article can be downloaded by clicking here. You will need the LINQ Preview (May 2006), available from the resources section below, to run the samples so you should be wary of installing it on your main or production machine. Use a Virtual Machine would be my advice.
Resources
Sample Code is available from here
LINQ Preview (May 2006) is available for download from here
Overview of Visual Basic 9.0
The LINQ Project - Don Box and Anders Hejlsberg
XLinq - .NET Language Integrated Query for XML Data May 2006 (Microsoft White Paper)
|