Softline

ОГЛАВЛЕНИЕ

Поиск по документу с XPath

XML Path Language (XPath) - язык, применяемый для получения наборов узлов XML-документа и адресации частей XML-документа. Он обеспечивает компактный, эффективный, логичный синтаксис для ссылок на узлы документа, тесно связан с XSLT и предоставляет стандартные средства для работы со строками, числами и булевскими значениями.

Пути в XPath формируются из названий узлов, разделенных слешами. Путь к товару будет описан следующим выражением.

Заказы/Заказ/Товар

Для идентификации элемента во всех местах документа нужно использовать два слеша в начале выражения:

//Товар 

Для указания неизвестных элементов в пути можно воспользоваться символом *. Например, можно задать вот такой путь для поиска руководителей отделов

Отделы/*/Руководитель

Для фильтрации элементов документа нужно использовать предикаты - выражения, заключенные в квадратные скобки. В предикатах могут участвовать атрибуты тегов и значения вложенных тегов. При этом, перед атрибутами тегов, участвующих в фильтрации, ставиться амперсанд @, а перед вложенными тегами - нет. Предикаты можно объединять ключевыми словами or и and. Для нахождения заказов из Москвы или Уфы нужно использовать такое выражение:

Заказы/Заказ[@Адрес = "Уфа" or @Адрес = "Москва"]

Для работы с XPath в .NET используются классы XPathNavigator и XPathNodeIterator. XPathNavigator выполняет XPath запросы, а перемещение по узлам, полученным в результате запроса осуществляется с помощью XPathNodeIterator. С помощью XPathNavigator можно перемещаться по документу в произвольном направлении. Для перехода к родительскому узлу есть метод MoveToParent, а для переход к первому дочернему узлу - MoveToFirstChild. Свойство HasChildren возвращает true если у текущего узла есть дочерние. Для перебора атрибутов текущего узла есть методы MoveToFirstAttribute, MoveToNextAttribute. В нашей программе мы используем XPath для поиска товаров, стоимостью более 300 рублей, и нахождения их суммарной стоимости. Рассмотрим эту функцию. 

OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "Файлы XML (*.xml)|*.xml"; if (dlg.ShowDialog() ! = DialogResult.OK)
    return;

XmlDocument doc = new XmlDocument();
orders.Clear();

try
{
    doc.Load(dlg.FileName);

    // находим стоимость всех товаров
    XPathNavigator nav = doc.CreateNavigator();
    XPathNodeIterator it = (XPathNodeIterator)nav.Evaluate("Заказы/Заказ/Товар[@Цена > 300]");

    StringBuilder sb = new StringBuilder();
    sb.Append("Дорогие товары:");
    float total = 0;

    while (it.MoveNext())
    {
         sb.AppendFormat("\n{0}", it.Current.GetAttribute("Цена", ""));
         total += float.Parse(it.Current.GetAttribute("Цена", ""));
    }

    sb.AppendFormat("\n--------------------\nИтого: {0} рублей", total);

    // получаем все заказы
    XmlNodeList ordersList = doc.DocumentElement.ChildNodes;

    foreach (XmlNode nodeOrder in ordersList)
    {
        Order order = new Order(nodeOrder.Attributes["Адрес"].Value, DateTime.Parse(nodeOrder.Attributes["Дата"].Value));

        // получаем все товары из заказа
        XmlNodeList goodsList = nodeOrder.ChildNodes;

        foreach (XmlNode nodeGood in goodsList)
            order.AddGood(nodeGood.Attributes["Название"].Value, float.Parse(nodeGood.Attributes["Цена"].Value));

        orders.Add(order);
    }

    ShowOrders();

    // выводим адреса заказов
    MessageBox.Show(sb.ToString());
}
catch (Exception ex)
{
    MessageBox.Show("Ошибка: " + ex.Message);
}

На первом этапе мы создаем XmlDocument и загружаем XML-файл, указанный пользователем. Объект XPathNavigator создается вызовом метода CreateNavigator. Мы выполнили XPath-запрос с помощью метода Evalate, выполняющим произвольный запрос. Результатом может быть число, строка, булевское значение или набор узлов, как в нашем случае. Этот метод мы выбрали только для примера, т.к. для получения именно набора узлов лучше пользоваться методом Select. Он также принимает строку с XPath выражением, но сразу возвращает объект XPathNodeIterator. В нашем примере мы искали все товары, цена которых более 300 рублей. Для перебора всех узлов, найденных методом Evalate, вызываем метод MoveNext() и для каждого узла получаем значение атрибута Цена. Все найденные цены суммируются, а из значения сохраняются в текстовом виде в StringBuilder.

 

Кондратьев Денис 

Читайте также:
  • COM+ и .NET – практичный подход - часть 1
    Вторая часть описывает все управляющие преимущества, которые приложение может получить от COM+. Эта часть содержит подробности об улучшении доступности и стабильности с помощью COM+ и о том, кого надо отслеживать и как использовать данные слежения для быстрого и легкого обнаружения источников проб...
  • Межпроцессная коммуникация посредством .NET
    •    Загрузить демо-проект - 85.41 KB•    Загрузить исходный код - 11.99 KB Введение Данная статья показывает быструю и простую в применении реализацию для связи между доменами приложений в .NET путем использования родной передачи сообщений Windows. Библиотека XDMessaging основана на коде, раз...
  • Передача данных из SAP в .NET с помощью ERPConnect
    • Скачать пример 1 (C#) - 7.35 Кб• Скачать пример 1 (VB.NET) - 12.57 Кб• Скачать пример 2 (C#) - 15.14 Кб• Скачать пример 2 (VB.NET) - 16.38 Кб Введение В проекте для последнего заказчика пришлось реализовать своего рода "программу быстрого заказа" для компании-производителя машин. Целью этого п...
  • Потоки и синхронизация: часть 1
    Введение Современная многопроцессорная операционная система выполняет несколько операций одновременно, даже если в системе есть только один физический процессор. Теоретически это кажется невозможным, но рассмотрим, как достигается параллельная обработка с помощью одного процессора. Есть много эт...
  • Формат файла .NET – внутренняя структура сигнатур, часть 2 из 2
    •    Скачать двоичные DLL примеров программ – signatures_binary.zip - 16.07 Кб•    Скачать исходный код примеров программ - signatures_source.zip - 6.14 KB Оглавление 1. Сигнатуры (продолжение) 1.1 LocalVarSig 1.2 CustomAttrib 1.3 MethodSpec 1.4 TypeSpec 1.5 MarshalSpec 2. Элементы ...