TOC

This article is currently in the process of being translated into French (~35% done).

XML:

Using XPath with the XmlDocument class

Dans un chapitre précédent, nous avons utilisé la classe "XmlDocument" pour récupérer les informations d'un fichier XML. Nous l'avons fait en utilisant une plage d'appels à la propriété ChildNodes, laquelle était plutôt facile parce que l'exemple utilisé était simple. De plus, cela ne facilite pas la lecture de notre code, c'est pour cela que dans ce chapitre nous allons voir une autre approche, qui est définitivement plus efficiente et facile à exploiter. La technologie que nous utiliserons pour cela est appeler "XPath" et est entretenue par la même organisation qui a créé le standard XML. XPath est un langage de requête, avec beaucoup de possibilités, mais comme ce n'est pas un tutoriel sur le XPath, nous utiliserons que des requêtes basiques. Même dans leurs formes simplifiées, les requêtes XPath sont tout de même puissantes, comme vous pourrez le voir dans les exemples suivants.

La classe XmlDocument a quelques méthodes qui prennent une requête XPath comme paramètre et retourne le noeud XML résultant. Dans ce chapitre, nous allons voir deux méthodes: SelectSingleNode(), qui retourne un XmlNode unique basé sur la requête XPath fournit, et SelectNodes(), qui retourne une XmlNodeList, une collection d'objet XmlNode basé sur la requête fournit.

Nous allons essayé les deux méthodes mentionnées plus haut, mais plutôt que d'utiliser les informations du fichier XML des chapitres précédents, nous allons essayer avec un fichier XML source. Les flux RSS sont des documents XML construit d'une façon particulière, pour permettre à une multitude de nouveaux lecteurs d'analyser et d'afficher les mêmes informations à leur manière.

We will use an RSS feed from CNN, located at http://rss.cnn.com/rss/edition_world.rss, with news from across the world. If you open it in your browser, your browser may render this in a nice way, allowing you to get an overview of the feed and subscribe to it, but don't get fooled by that: Under the hood, it's just XML, which you will see if you do a "View source" in your browser. You will see that the root element is called "rss". The rss element usually has one or several "channel" elements, and within this element, we can find information about the feed as well as the "item" nodes, which are the news items we usually want.

In the following example, we will use the SelectSingleNode() method to get the title of the feed. If you look at the XML, you will see that there is a <title> element as a child element of the <channel> element, which is then a child element of the <rss> element, the root. That query can be described like this in XPath:

//rss/channel/title

We simply write the names of the element we're looking for, separated with a forward-slash (/), which states that the element should be a child to the element before the preceeding forward-slash. Using this XPath is as simple as this:

using System;
using System.Text;
using System.Xml;

namespace ParsingXml
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("http://rss.cnn.com/rss/edition_world.rss");
            XmlNode titleNode = xmlDoc.SelectSingleNode("//rss/channel/title");
            if(titleNode != null)
                Console.WriteLine(titleNode.InnerText);
            Console.ReadKey();   
        }
    }
}

We use the SelectSingleNode() method to locate the <title> element, which simply takes our XPath as a string parameter. We then check to make sure that it returned a result, and if it did, we print the InnerText of the located node, which should be the title of the RSS feed.

In the next example, we will use the SelectNodes() method to find all the item nodes in the RSS feed and then print out information about them:

using System;
using System.Text;
using System.Xml;

namespace ParsingXml
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("http://rss.cnn.com/rss/edition_world.rss");
            XmlNodeList itemNodes = xmlDoc.SelectNodes("//rss/channel/item");
            foreach(XmlNode itemNode in itemNodes)
            {
                XmlNode titleNode = itemNode.SelectSingleNode("title");
                XmlNode dateNode = itemNode.SelectSingleNode("pubDate");
                if((titleNode != null) && (dateNode != null))
                    Console.WriteLine(dateNode.InnerText + ": " + titleNode.InnerText);
            }
            Console.ReadKey();   
        }
    }
}

The SelectNodes() method takes an XPath query as a string, just like we saw in the previous example, and then it returns a list of XmlNode objects in a XmlNodeList collection. We iterate through it with a foreach loop, and from each of the item nodes, we ask for a child node called title and pubDate (published date) using the SelectSingleNode() directly on the item node. If we get both of them, we print out the date and the title on the same line and then move on.

In our example, we wanted two different values from each item node, which is why we asked for the item nodes and then processed each of them. However, if we only needed the e.g. the titles of each item, we could change the XPath query to something like this:

//rss/channel/item/title

It will match each title node in each of the item nodes. Here's the query with some C# code to make it all happen:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("http://rss.cnn.com/rss/edition_world.rss");
XmlNodeList titleNodes = xmlDoc.SelectNodes("//rss/channel/item/title");
foreach(XmlNode titleNode in titleNodes)
    Console.WriteLine(titleNode.InnerText);            
Console.ReadKey();
This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!