Страница 7 из 7 Поиск по документу с 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. Кондратьев Денис |