XElement Refresher

In this day and age of JSON data everywhere, a lot of developers are leaving XML behind. There are, however, still some areas where XML is still used quite heavily; web and application configuration files are a start. There are also many financial institutions that still do pretty much everything internal to a core banking system in XML.

.NET has always had great support for handling XML data, and there are certainly more than a handful of different APIs for dealing with it. In this article, I'm going to go over a quick refresher of using the XElement interface, and in the process introduce you to one place where XML is still used that's potentially quite useful to you.

Constructing XML

The XElement interface makes it almost childlike to construct valid XML. Let's imagine for a moment we wanted to create something that looks similar to the following XML data:

<person>
   <name>Peter Shaw</name>
   <email>shawty.d.ds@googlemail.com</email>
</person>

Using XElement to construct this is a simple as using the following code:

using System;
using System.Xml.Linq;

namespace blogxelementrefresh
{
   class Program
   {
      static void Main()
      {
         XElement myRoot = new XElement("person");
         myRoot.Add(new XElement("name", "Peter Shaw"));
         myRoot.Add(new XElement("email",
            "shawty.d.ds@googlemail.com"));

         Console.Write(myRoot.ToString());
      }

   }
}

If we press F5 to run this, we get the following in our console window:

Refresh1
Figure 1: The results of running the preceding code

Very easy, and very simple to understand.

Adding nested elements is not any harder either.

using System;
using System.Xml.Linq;

namespace blogxelementrefresh
{
   class Program
   {
      static void Main()
      {
         XElement myRoot = new XElement("person");
         myRoot.Add(new XElement("name",
            "Peter Shaw"));
         myRoot.Add(new XElement("email",
            "shawty.d.ds@googlemail.com"));

         XElement nestedElement =
            new XElement("location");
         nestedElement.Add(new XElement("area",
            "North Durham"));
         nestedElement.Add(new XElement("country",
            "United Kingdom"));

         myRoot.Add(nestedElement);

         Console.Write(myRoot.ToString());
      }

   }
}

Which, when run, gives us the following:

Refresh2
Figure 2: After running the code containing nested elements

By combining multiple levels of elements, it's possible to very simply build an XML structure to match anything you need; then, by using the 'ToString' method on the root element, get an appropriately formatted string ready to save into a file. XElement also makes it easy to parse XML. To demonstrate that, however, we need a source of XML data.

Many of you who have a Gmail account may not know this, but it's possible to get an XML summary of your Gmail inbox, and very easily too. If you point your browser at

https://mail.google.com/mail/feed/atom

and enter your Gmail user name and password when prompted, you can take a look at the output in your browser.

Refresh3
Figure 3: Viewing the preceding output in a browser

You can easily retrieve this feed in a .NET program by using the WebClient class and an old-fashioned base64 encrypted access request. Needless to say, you must do this over HTTPS. In fact, Google doesn't give you any choice; it's HTTPS or bust. You can grab the XML data by using the following code:

string gmailFeed;

using (WebClient client = new WebClient())
{
   client.Credentials = new
      NetworkCredential("user", "password");
   gmailFeed = client.DownloadString
      ("https://mail.google.com/mail/feed/atom");
}

If you still have problems accessing the feed when using this procedure, you may also need to configure your GMail account settings to allow 'Less Secure apps' to access the account. Generally, if this is the case, you'll get an automatic EMail to your alternative email address, warning you of the fact.

Refresh4
Figure 4: Google-generated warning

The second link in the EMail will take you to the following page:

Refresh5
Figure 5: The Google page where you can allow access

where you can allow your application to have access. Once you have the received XML in a regular string, you then can parse it using XElement as follows:

XElement gmailDoc = XElement.Parse(gmailFeed);

Because the XML is an 'Atom' feed, you'll also need to create a namespace:

XNamespace ns = "http://purl.org/atom/ns#";

Then, with all that done, it's simply just a matter of extracting the information you need. The following code shows the inbox title and message count, then outputs a summary of all the waiting emails available.

Console.WriteLine(gmailDoc.Element(ns +
   "title").Value);
Console.WriteLine("{0} {1}",
   gmailDoc.Element(ns + "fullcount").Value,
   gmailDoc.Element(ns + "tagline").Value);
Console.WriteLine();

foreach (XElement entry in gmailDoc.Elements(ns +
   "entry"))
{
   Console.WriteLine(entry.Element(ns +
      "title").Value);
   Console.WriteLine(entry.Element(ns +
      "summary").Value);
   Console.WriteLine(entry.Element(ns +
      "author").Element(ns + "email").Value);
   Console.WriteLine();
}

Grabbing a single element is as easy as using the 'Element' method with the name (optionally prefixed with a namespace) of the element you wish to retrieve. To get an IEnumerable collection, use the 'Elements' method instead. There are others, too, but I leave exploring them to you, the reader.

Got something in .NET you'd like to know more about, or a trick you'd like to share, feel free to drop a comment in the comments section below or bend my ear on Twitter where I can usually be found as @shawty_ds. Let me know if there's anything you'd like to see covered in this column.



Related Articles

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date