Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Поиск строк (записей) в 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; просмотров: 1491; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.116.43.109 (0.008 с.) |