TOC

This article has been localized into German by the community.

XML:

XPath mit der XmlDocument-Klasse benutzen

In einem früheren Kapitel haben wir die Klasse XmlDocument verwendet, um Informationen aus einer XML-Datei zu erhalten. Wir haben es getan, indem wir eine Reihe von Aufrufen der ChildNodes-Eigenschaft verwendet haben. Das was einfach, weil das Beispiel sehr einfach war. Es hat aber der Lesbarkeit unseres Codes nicht gut getan, so dass wir in diesem Kapitel einen anderen Ansatz betrachten werden, der definitiv leistungsfähiger und dennoch einfacher zu lesen und zu pflegen ist. Die Technologie, die wir dafür verwenden werden, heißt XPath und wird von der gleichen Organisation verwaltet, die auch den XML-Standard erstellt hat. XPath ist eigentlich eine ganze Abfragesprache mit vielen Möglichkeiten, aber weil das hier kein XPath-Tutorial ist, werden wir uns nur mit einigen grundlegenden Abfragen befassen. Doch selbst in seinen einfachsten Formen ist XPath immer noch mächtig, wie Sie in den folgenden Beispielen sehen werden.

Die Klasse XmlDocument verfügt über mehrere Methoden, die eine XPath-Abfrage als Parameter erhalten und dann die resultierenden XmlNode(s) zurückgeben. In diesem Kapitel werden wir uns mit zwei Methoden beschäftigen: Die SelectSingleNode()-Methode, die eine einzelnen XmlNode basierend auf der angegebenen XPath-Abfrage zurückgibt, und die SelectNodes()-Methode, die eine XmlNodeList-Sammlung von XmlNodeObjekten basierend auf der angegebenen XPath-Abfrage zurückgibt.

Wir werden beide der oben genannten Methoden ausprobieren, aber anstatt das XML mit Währungsinformationen zu verwenden, das wir in den vorherigen Kapiteln getestet haben, werden wir nun eine neue XML-Quelle ausprobieren. RSS-Feeds sind im Wesentlichen XML-Dokumente, die auf eine bestimmte Weise erstellt wurden, um einer Vielzahl von verschiedenen Newsreadern zu ermöglichen, dieselben Informationen auf ihre eigene Weise zu analysieren und anzuzeigen.

Wir werden einen RSS-Feed von CNN verwenden, der sich unter http://rss.cnn.com/rss/edition_world.rss befindet und Nachrichten aus der ganzen Welt enthält. Wenn Sie es in Ihrem Browser öffnen, kann Ihr Browser dies schön formatiert darstellen, so dass Sie sich einen Überblick über den Feed verschaffen und ihn abonnieren können, aber lassen Sie sich davon nicht täuschen: Unter der Haube ist es nur XML, das Sie sehen werden, wenn Sie "Seitenquelltext anzeigen" in Ihrem Browser aufrufen. Sie werden sehen, dass das Wurzelelement "rss" heißt. Das RSS-Element hat in der Regel ein oder mehrere "Channel"-Elemente, und innerhalb dieser Elemente finden wir Informationen über den Feed sowie die Knoten "Item", der die Nachrichten enthält, die wir normalerweise wollen.

Im folgenden Beispiel verwenden wir die SelectSingleNode()-Methode, um den Titel des Feeds zu erhalten. Wenn Sie sich das XML ansehen, werden Sie sehen, dass es ein <title> Element als untergeordnetes Element des <channel> Elements gibt, das dann ein untergeordnetes Element des <rss> Elements, der Wurzel ist. Diese Abfrage kann in XPath so beschrieben werden:

//rss/channel/title

Wir schreiben einfach die Namen des gesuchten Elements, getrennt durch einen Schrägstrich (/), der besagt, dass das Element ein Kind des Elements vor dem Schrägstrich sein sollte. Die Verwendung dieses XPath im Code ist sehr einfach:

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();   
        }
    }
}

Wir verwenden die SelectSingleNode()-Methode, um das Element <title> zu finden, das unseren XPath einfach als Zeichenkettenparameter erhält. Wir überprüfen dann, ob es ein Ergebnis zurückgegeben hat, und wenn ja, zeigen wir den InnerText des gefundenen Knotens an, der der Titel des RSS-Feeds sein sollte.

Im nächsten Beispiel werden wir die SelectNodes()-Methode verwenden, um alle "item"-Knoten im RSS-Feed zu finden und dann Informationen über sie auszugeben:

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();   
        }
    }
}

Die SelectNodes()-Methode nimmt eine XPath-Abfrage als Zeichenkette, wie wir es im vorherigen Beispiel gesehen haben, und gibt dann eine Liste von XmlNode-Objekten in einer XmlNodeList-Sammlung zurück. Wir iterieren durch sie mit einer foreach-Schleife, und von jedem der "item"-Knoten fragen wir nach einem Kind-Knoten namens "title" und "pubDate" (Veröffentlichungsdatum) mit dem SelectSingleNode() direkt auf dem "item"-Knoten. Wenn wir beide bekommen, zeigen wir das Datum und den Titel in der gleichen Zeile an und gehen dann weiter.

In unserem Beispiel wollten wir von jedem "item"-Knoten zwei verschiedene Werte, weshalb wir nach den "item"-Knoten gefragt und dann jeden von ihnen verarbeitet haben. Wenn wir jedoch nur die z.B. die Titel der einzelnen Elemente benötigen, können wir die XPath-Abfrage so ändern:

//rss/channel/item/title

Es wird jedem Titelknoten in jedem der Elementknoten zugeordnet. Hier ist die Abfrage mit etwas C#-Code:

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!