TOC

This article has been localized into Russian by the community.

XML:

Использование XPath с классом XmlDocument

В предыдущей главе мы читали XML-файл с помощью класса XmlDocument. Мы сделали это через доступ к свойству ChildNodes, что было легко, потому что пример был очень простым. Это не делало наш код особенно читабельным, поэтому в этой главе мы рассмотрим другой подход, более мощный и более простой для понимания и поддержки. Технология, которую мы будем использовать называется XPath и поддерживается той же организацией, которая разработала стандарт XML. XPath - это фактически целый язык запросов с множеством возможностей, но поскольку это не учебник по XPath, мы рассмотрим только базовые запросы. Тем не менее даже в этих простейших формах XPath достаточно мощный, как вы сможете увидеть в следующих примерах.

В классе XmlDocument есть несколько методов, принимающих запрос XPath в качестве параметра и затем возвращающих результирующий узел или узлы XmlNode. В этой главе мы рассмотрим два метода. Метод SelectSingleNode(), который возвращает один XmlNode, на основе переданного запроса XPath, и метод SelectNodes(), который возвращает коллекцию объектов XmlNode (XmlNodeList), на основе переданного запроса XPath.

Мы попробуем оба эти метода, но вместо XML-данных о валюте, которые мы обрабатывали в предыдущих главах, мы попробуем новые данные XML. RSS-каналы - это в сущности XML-документы, собранные особым образом, чтобы позволить разным читателям новостей загружать, обрабатывать и отображать одну и ту же информацию по-своему.

Мы будем использовать RSS-каналы из CNN, которые можно найти по ссылке http://rss.cnn.com/rss/edition_world.rss, с новостями со всего мира. Если вы откроете ссылку в своем браузере, ваш браузер сможет представить все это в удобном виде, позволяя вам увидеть обзор канала и подписаться на него, однако внутри это просто XML, который можно увидеть, если выбрать "Просмотреть код" в вашем браузере. Вы увидите, что корневой элемент называется "rss". Элемент rss обычно содержит один или несколько элементов "channel", и внутри этого элемента мы можем найти информацию о ленте новостей, а также узлы "item", являющиеся как раз теми новостями, которые мы хотим получить.

В следующем примере мы будем использовать метод SelectSingleNode(), чтобы получить заголовок новостей. Если вы посмотрите XML, вы увидите элемент <title> в качестве дочернего для элемента <channel>, который в свою очередь является дочерним для элемента <rss>, корневого. Этот запрос можно описать в XPath следующим образом:

//rss/channel/title

Мы просто записали имена искомых элементов, разделенные прямым слэшем (/), который показывает, что элемент должен быть дочерним для элемента, расположенного до прямого слэша. Использование такого XPath просто, как показано ниже:

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

Мы используем метод SelectSingleNode(), чтобы получить элемент <title>, который принимает наш XPath как параметр. Затем мы проверяем, что был возвращен результат и если был, выводим на экран InnerText этого узла, который и должен оказаться заголовком новости.

В следующем примере мы будем использовать метод SelectNodes(), чтобы найти все узлы элементов в новостях и вывести на экран информацию о них:

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

Метод SelectNodes() принимает запрос XPath как строку, как мы видели в предыдущем примере, и затем возвращает список объектов XmlNode в коллекцию XmlNodeList . Мы проходимся в цикле по каждому из них и по каждому элементу узла, запрашивая дочерний узел с именем title (заголовок) и pubDate (published date - дата публикации), используя SelectSingleNode() элемента узла. Если мы получили и то и другое, выводим на экран дату и заголовок в одну строку и движемся дальше.

В нашем примере мы хотели получить два разных значения из каждого элемента узла, вот почему мы запрашивали элементы узлов и затем рассматривали каждый из них. Однако если нам нужны только заголовки, мы должны изменить запрос XPath, как показано ниже:

//rss/channel/item/title

Он будет соответствовать каждому узлу title в каждом из элементов узлов. Ниже приводится запрос с кодом С#, чтобы все это выполнить:

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!