Поиск строк (записей) в XML-данных с помощью LINQ-запроса 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Поиск строк (записей) в XML-данных с помощью LINQ-запроса



Имеем XML-данные, в которых содержится традиционная для нашей книги таблица с именами и телефонами, причем имена в этой телефонной табличке по­вторяются, например, строка с именем "Витя" содержит мобильный телефон, а по­том по мере знакомства с этим Витей у нас появился уже и его домашний телефон. Задача состоит в том, чтобы в данной таблице телефонов (представленной в виде XML, см. листинг 11.8) найти все строчки с именем "Витя". Эта маленькая несерь­езная, на первый взгляд, задача подразумевает, например, такую уже "серьезную" задачу. Имеем громадную базу данных, которую мы получили на каком-то этапе обработки в виде XML, и нам требуется "отфильтровать" записи в этой базе на предмет содержания в некотором поле определенной строки.

Прежде чем решать данную задачу, давайте посмотрим отображение обсуж­даемых XML-данных в табличном редакторе MS Excel (рис. 19.11).

Рисунок 19.11 - Отображение XML-данных в MS Excel

Как видно, в редакторе MS Excel наши XML-Данные представлены весьма на­глядно. И очень понятно, что мы хотим получить, а именно, все номера телефонов напротив имени "Витя".

Для решения этой задачи запустим Visual Studio 2010 и выберем проект шабло­на Windows Forms Application, укажем имя Name — Linq5. Далее, попав в конст­руктор формы, из панели элементов Toolbox перетащим текстовое поле TextBox для вывода в него найденных строк из таблицы XML. В свойствах текстового поля разрешим ввод множества строк (а не одной), для этого свойство Multiline пере­ведем в состояние true. Затем на вкладке программного кода введем текст, пред­ставленный в листинге 19.8.

Листинг 19.8. Извлечение значения элемента из XML-данных

// Имеем XML-данные, в которых содержатся таблица с именами и телефонами, причем

// имена в этой телефонной табличке повторяются. Задача состоит в том, чтобы в

// данной таблице телефонов (представленной в виде XML) найти все строчки c

// именем "Витя" с помощью LINQ-запроса.

using System.Linq;

using System.Windows.Forms;

// Другие директивы using удалены, поскольку они не используются в данной программе

namespace Linq5

{

public partial class Form1: Form

{

public Form1()

{

InitializeComponent();

this.Text = "LINQ-запрос к XML-данным"; textBox1.Multiline = true;

// Инициализация XML-строки:

string СтрокаXML =

@"<?xml version=""1.0""?>

<ТаблицаТелефонов>

<Строка>

<Имена>Витя</Имена>

<Номера_телефонов>274 28 44</Номера_телефонов>

</Строка>

<Строка>

<Имена>Андрей</Имена>

<Номера_телефонов>8-085-456-2378</Номера_телефонов>

</Строка>

<Строка>

<Имена>Карапузова Таня</Имена>

<Номера_телефонов>445-56-47</Номера_телефонов>

</Строка>

<Строка>

<Имена>Витя</Имена>

<Номера_телефонов>099 72 161 52</Номера_телефонов>

</Строка>

<Строка>

<Имена>Никипелов</Имена>

<Номера_телефонов>236-77-76</Номера_телефонов>

</Строка>

<Строка>

<Имена>Зиборов</Имена>

<Номера_телефонов>254 67 97</Номера_телефонов>

</Строка>

</ТаблицаТелефонов>";

var КорневойЭлемент = System.Xml.Linq.XElement.Parse(СтрокаXML);

// Запись строки, содержащей XML в файл:

// System.IO.File.WriteAllText("ТаблицаТелефонов.xml", СтрокаXML);

// var КорневойЭлемент = System.Xml.Linq.

// XElement.Load("ТаблицаТелефонов.xml");

var Записи =

from x in КорневойЭлемент.Elements("Строка")

where (string)x.Element("Имена") == "Витя"

select x.Element("Номера_телефонов").Value;

textBox1.Text = textBox1.Text +

@"Строки, содержащие имя ""Витя"":" + "\r\n";

// Вывод коллекции записей в текстовое поле textBox1:

foreach (var x in Записи)

textBox1.Text = textBox1.Text + x + "\r\n";

// Таких записей в этой коллекции - ровно одна

}

}

}

Как видно, в начале программы мы инициализируем (т. е. присваиваем началь­ные значения) XML-строку. Далее извлекаем корневой элемент из XML-документа, он, по сути, отличается от XML-документа отсутствием XML-объявления (в этом можно убедиться в отладчике программы). В комментарии указано, как можно полу­чить корневой элемент в том случае, если он представлен в виде XML-файла во внешней памяти. Затем организуем типовой, стандартный LINQ-запрос. Результат запроса попадает в коллекцию записей, которую выводим в текстовое поле, исполь­зуя оператор цикла foreach. Фрагмент работы программы показан на рис. 19.12.

Рисунок 19.12 - LINQ-запрос к XML-документу

Убедиться в работоспособности программы можно, открыв решение Linq5.sln из папки Linq5.

5.8 LINQ-запрос к набору данных DataSet

Весьма полезной оказывается организация LINQ-запросов к наборам данных DataSet, используемым, к примеру, при работе с базами данных. Объект класса DataSet представляет расположенный в памяти кэш (cache) данных (кэш — это промежуточная память с быстрым доступом, содержащая информацию, которая может быть запрошена с наибольшей вероятностью). Реляционные базы данных работают чаще всего с совокупностью таблиц. Каждая из этих таблиц задается как объект класса DataTable, один такой объект представляет ровно одну таблицу дан­ных. Набор данных DataSet содержит в себе несколько объектов (таблиц) DataTable. Запросы LINQ к таблицам данных, кэшированным в объекте DataSet, упрощают и ускоряют процесс отбора.

Данная задача состоит в том, чтобы создать программу, которая обеспечивает ввод простейшей таблицы, содержащей два поля — название города и численность его населения. Программа способна фильтровать данные в таблице; будем произво­дить отбор городов, численность населения которых превышает миллион жителей.

Для решения этой задачи запустим Visual Studio 2010 и выберем проект шаблона Windows Forms Application, укажем имя Name — LinqГорода. Далее, попав в кон­структор формы, из панели элементов Toolbox перетащим элемент управления для отображения и редактирования табличных данных DataGridView, две командные кнопки Button и текстовое поле TextBox. Одна кнопка предназначена для команды сохранения данных, другая — для поиска данных в таблице, а текстовое поле — для вывода в него найденных строк из таблицы. В свойствах текстового поля разрешим ввод множества строк, для этого свойство Multiline переведем в состояние true. Затем на вкладке программного кода введем текст, представленный в листинге 19.9.

Листинг 19.9. Извлечение полей из набора данных DataSet

// В данной программе экранная форма содержит элемент управления для отображения

// и редактирования табличных данных DataGridView, две командные кнопки и текстовое

// поле. При старте программы, если есть соответствующий файл XML, то программа

// отображает в DataGridView таблицу городов - название города и численность

// населения. При щелчке на кнопке "Сохранить" все изменения в таблице записываются

// в XML-файл. При щелчке на второй кнопке "Найти" выполняется LINQ-запрос к набору

// данных DataSet на поиск городов-миллионеров в искомой таблице. Результат запроса

// выводится в текстовое поле.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

// Другие директивы using удалены, поскольку они не используются в данной программе

namespace LinqГорода

{

public partial class Form1: Form

{

DataTable Таблица = new DataTable(); // Создание объекта таблица данных

DataSet НаборДанных = new DataSet(); // Создание объекта набор данных

public Form1()

{

InitializeComponent();

base.Text = "LINQ-запрос к набору данных DataSet";

button1.Text = "Сохранить"; button2.Text = "Найти";

textBox1.Multiline = true;

if (System.IO.File.Exists("Города.xml") == false)

{

// Если XML-файла НЕТ:

// Заполнение "шапки" таблицы

Таблица.Columns.Add("Город"); Таблица.Columns.Add("Население");

// Добавить объект Таблица в DataSet

НаборДанных.Tables.Add(Таблица);

dataGridView1.DataSource = Таблица;

}

else // Если XML-файл ЕCТЬ:

{

НаборДанных.ReadXml("Города.xml");

// Содержимое DataSet в виде строки XML для отладки:

// string СтрокаXML = НаборДанных.GetXml();

Таблица = НаборДанных.Tables["Города"];

dataGridView1.DataMember = "Города";

dataGridView1.DataSource = НаборДанных;

}

}

private void button1_Click(object sender, EventArgs e)

{

// Щелчок мышью на кнопке "Сохранить" - сохранить файл Города.xml:

Таблица.TableName = "Города";

НаборДанных.WriteXml("Города.xml");

}

private void button2_Click(object sender, EventArgs e)

{

// Щелчок мышью на кнопке "Поиск" - запрос городов-миллионеров:

textBox1.Clear(); // - очистка текстового поля

var ГородаМлн = from Город in Таблица.AsEnumerable()

where Convert.ToInt32(Город.

Field<String>("Население")) >= 1000000

select new

{

A = Город.Field<string>("Город"),

B = Город.Field<string>("Население")

};

textBox1.Text = textBox1.Text + "Города-миллионеры:\r\n";

// Вывод результата запроса в текстовое поле textBox1:

foreach (var Город in ГородаМлн)

textBox1.Text = textBox1.Text + Город.A + " - " + Город.B + "\r\n";

}

}

}

В начале программы создаем объекты классов DataSet и DataTable так, чтобы они были видимыми из всех процедур класса Form1. Далее сразу после инициали­зации компонентов экранной формы (т. е. после выполнения процедуры InitializeComponent) проверяем, существует ли файл Города.xml, куда мы запи­сываем искомую таблицу. Если файл не существует, т. е. пользователь первый раз запустил нашу программу, то мы создаем таблицу, состоящую из двух полей (ко­лонок): "Город" и "Население", добавляем (Add) эту таблицу в набор данных, а также указываем таблицу в качестве источника данных (DataSource) для сетки данных dataGridView1. Если же файл Города.xml уже создан, то мы читаем его в набор данных DataSet и из него заполняем таблицу данных, а также этот набор данных указываем в качестве источника для сетки данных.

При обработке события "щелчок мышью на кнопке Запись ” программируем сохранение редактируемой таблицы в файле Города.хml. В процедуре обработки события "щелчок на кнопке" Найти организуем LINQ-запрос к заполненной поль­зователем таблице DataTable, являющейся представителем DataSet. Условием за­проса является отбор таких полей таблицы, где население превышает миллион жи­телей. Заметим, что если не задавать условие where, то в результате запроса получим все содержимое источника данных, т. е. все строки таблицы городов. Ре­зультат запроса выводим в текстовое поле, используя цикл foreach.

Фрагмент работы программы показан на рис. 19.13.

Убедиться в работоспособности программы можно, открыв решение LinqГорода.sln из папки LinqГорода.

Рисунок 19.13 - LINQ-запрос к набору данных



Поделиться:


Последнее изменение этой страницы: 2016-04-26; просмотров: 1446; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.118.193.232 (0.022 с.)