TOC

This article is currently in the process of being translated into French (~60% 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.

Nous utiliserons un flux RSS de CNN situé à l'emplacement http://rss.cnn.com/rss/edition_world.rss qui donne des informations sur les nouvelles du monde. Si vous l'ouvrez avec votre navigateur, celui-ci le présentera de façon agréable, vous laissant la possibilité de voir un résumé du flux et de vous y abonner, mais ne vous laissez pas duper par cela : sous cet apparence c'est juste du XML qui se cache, ce qui vous pouvez constater si vous affichez le code source de la page dans votre navigateur. Vous constaterez que l'élément racine du fichier XML est nommé "rss". Un élément "rss "possède un ou plusieurs éléments "channel" et sous chacun de ces éléments vous trouvez les informations concernant le flux et les nœuds "item" qui sont les différentes rubriques d'information que l'on souhaite habituellement consuter

Dans l'exemple suivant, nous utiliserons la méthode SelectSingleNode() pour obtenir le titre du canal de diffusion. Si vous jeter un coup d'oeil au XML, vous verrez qu'il y a un élément title comme élément enfant (child) de l'élément channel, qui est lui-même élément enfant de l'élément rss qui est la racine (root). Cette requête peut être décrite ainsi avec 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!