There are mainly two methods for reading XML with C#: The XmlDocument class and the XmlReader class. XmlDocument reads the entire XML content into memory and then lets you navigate back and forward in it as you please, or even query the document using the XPath technology.
The XmlReader is a faster and less memory-consuming alternative. It lets you run through the XML content one element at a time, while allowing you to look at the value, and then moves on to the next element. By doing so, it obviously consumes very little memory because it only holds the current element, and because you have to manually check the values, you will only get the relevant elements, making it very fast. In this chapter, we will focus on the XmlReader class, and then move onto the XmlDocument class in the next chapter.
Let's try a little example, where we read an XML document containing currency rates. Fortunate for us, the European Central Bank has one that we can use. We could download it and read it from the harddrive, but actually, both the XmlReader and the XmlDocument classes can read XML from a remote URL just as well as from a local file. You can see the XML here (http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml) and here comes some code and then an explanation of it:
static void Main(string args)
XmlReader xmlReader = XmlReader.Create("http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml");
if((xmlReader.NodeType == XmlNodeType.Element) && (xmlReader.Name == "Cube"))
Console.WriteLine(xmlReader.GetAttribute("currency") + ": " + xmlReader.GetAttribute("rate"));
We start off by creating the XmlReader instance, using the static Create() method. It has several overloads, but the simplest of them just takes a URL pointing to the file. In a while loop, we call the Read() method on the XmlReader instance. It advances the reader to the next element and then returns true as long as there is more to read. Inside the loop, we can now use one of the many properties and methods on the XmlReader to access data from the current element.
In our case, we check the NodeType to see if we have an Element (the tag part), and if the name is "Cube". As you can see in the XML document we used, each currency rate is within an element called Cube, so this is of course what we're looking for - the rest is ignored. Once we have a Cube element, we do a formal check to see if it has attributes (which it should) and then we use the GetAttribute() method to read the two attribute values "currency" and "rate". We print them out to the Console and then we move on to the next element. The result should be a complete list of currencies and their current exchange rate.
As you can see, this is pretty simple to do, but mainly because we just need the data in the same order as they are read, without doing anything fancy to it. In the next chapter, we will do the same thing but using the XmlDocument class, so that you can see the difference.
Note: You should be aware that there are many ways in which the above code could fail and throw an exception, which you should of course handle. See the chapter on exceptions for more information.