Технология Microsoft ADO.NET

       

Загрузка XML-документов и XSD-схем в типизированный объект DataSet


Мы привыкли получать данные для объекта DataSet из базы Microsoft Access или SQL. Между тем можно загружать данные непосредственно из XML-файла с встроенной схемой или без нее. Для этого применяется метод ReadXml, который является перегруженным и может использоваться для чтения из XML-файла, из объекта подкласса TextReader, из объекта потока или из подкласса XmlReader (рис. 11.25):


увеличить изображение
Рис. 11.25.  Перегруженный метод ReadXml

Метод ReadXml вторым параметром принимает XmlReadMode, применяемый для задания того, что содержит XML-файл и какая информация должна быть из него загружена. Этот параметр не обязателен, и если он не указан, используется значение по умолчанию - Auto. В таблице 11.8 приводятся другие значения параметра XmlReadMode.

Таблица 11.8. Значения параметра XmlReadMode

ЗначениеОписание
ReadSchema Загружает и данные, и схему. Если в DataSet уже есть схема, таблицы из встроенной схемы добавляются. В случае, когда хотя бы одна из добавляемых таблиц уже есть в DataSet, генерируется исключение. При загрузке в объект DataSet, не содержащий схемы, XML-файла также без схемы - данные не будут прочитаны
IgnoreSchema Игнорирует встроенную схему и загружает данные в уже имеющуюся схему DataSet. Не подходящие к этой схеме данные отбрасываются. Если в DataSet нет схемы, то данные не будут прочитаны
InferSchema Игнорирует встроенную схему и выводит схему из структуры данных XML в файле. Если в DataSet уже есть схема, она расширяется путем добавления новых таблиц или путем добавления столбцов в уже существующие таблицы
DiffGram Читает объект DiffGram и добавляет данные в уже существующую схему. (DiffGram-документ содержит всю информацию о данных объекта DataSet, включая первоначальное и текущее значение строк. Эти сведения можно использовать для проведения слияния объектов DataSet или обновления базы данных)
Fragment Читает фрагменты XML до конца потока. Данные, соответствующие схеме DataSet, добавляются в конец нужной таблицы; несоответствующие - отбрасываются.
Auto Используется по умолчанию. Исследует данные XML и выбирает наиболее подходящий режим:
  • Если XML-документ является объектом DiffGram - используется значение DiffGram;
  • Если DataSet содержит схему или XML-документ содержит встроенную схему - используется значение ReadSchema;
  • Если ни DataSet, ни XML не содержат схемы - используется значение InferSchema
<
Для загрузки XSD-схемы в объект DataSet применяется метод ReadXmlSchema. Этот метод является перегруженным, так что можно указать источник информации в одном из следующих видов: имя файла, объект подкласса TextReader, поток или объект подкласса XmlReader (рис. 11.26):


Рис. 11.26.  Перегруженный метод

Скопируйте папку приложения StructureTypedDataSet и назовите ее "TypedDataSetReadXML5)". Открываем проект, перетаскиваем на форму элемент управления MainMenu и создаем следующие пункты (рис. 11.27):


Рис. 11.27.  Пункты главного меню приложения TypedDataSetReadXML

NameText
MnuFile &Файл
MnuFill &Заполнить
MnuOpen &Открыть
MnuAuto &Auto
mnuDiffGram &DiffGram
mnuFragment &Fragment
mnuIgnoreSchema I&gnore Schema
mnuInferSchema &Infer Schema
mnuReadSchema &Read Schema
mnuReadXmlSchema Открыть &схему
Добавляем элемент управления OpenFileDialog, в его свойстве Filter вводим строку для расширений файлов:

XML and XSD Files(*.xml, *.xsd)| *.xml; *.xsd; |All Files(*.*)|*.*

Переходим в код формы. Создаем метод ClearForm, который будет удалять содержимое формы:

private void ClearForm() { dsTour.Clear(); dataGrid1.DataSource = null; richTextBox1.Text = ""; }

Создаем метод StructureDataSet, задача которого - выводить в элемент richTextBox1 структуру типизированного объекта DataSet. Соответствующий фрагмент кода вырезаем из конструктора формы:

private void StructureDataSet() { //Код для вывода структуры объекта DataSet }

Создаем обработчик пункта главного меню "Заполнить". Фрагмент кода для извлечения данных также вырезаем из конструктора формы:

private void mnuFill_Click(object sender, System.EventArgs e) { ClearForm(); //Код для извлечения данных из базы BDTur_firm_Eng.mdb StructureDataSet(); }

Подключаем пространство имен для работы с потоками:

using System.IO;

Создаем обработчик пункта "Auto", в котором делаем переключатель различных значений параметра XmlReadMode. Дополнительно содержимое файла в виде простого текста будет выводиться в элемент richTextBox:



private void mnuAuto_Click(object sender, System.EventArgs e) { ClearForm(); if(openFileDialog1.ShowDialog() == DialogResult.OK) { XmlReadMode readMode = XmlReadMode.Auto; MenuItem menuItem = (MenuItem)sender; switch(menuItem.Index) { case 0: readMode = XmlReadMode.Auto; break; case 1: readMode = XmlReadMode.DiffGram; break; case 2: readMode = XmlReadMode.Fragment; break; case 3: readMode = XmlReadMode.IgnoreSchema; break; case 4: readMode = XmlReadMode.InferSchema; break; case 5: readMode = XmlReadMode.ReadSchema; break; } dsTour.ReadXml(openFileDialog1.FileName, readMode); dataGrid1.DataSource = dsTour; // Создаем поток для заполнения элемента richTextBox1 FileStream filestream= File.Open(openFileDialog1.FileName, FileMode.Open, FileAccess.Read); //Проверяем, открыт ли поток, и если открыт, выполняем условие if(filestream != null) { //Создаем объект streamreader и связываем его с потоком filestream StreamReader streamreader = new StreamReader(filestream); //Считываем весь файл и записываем его в TextBox richTextBox1.Text = streamreader.ReadToEnd(); //Закрываем поток. filestream.Close(); } } }

Аналогично, в обработчике пункта меню "Открыть схему" используем метод ReadXmlSchema объекта DataSet:

private void mnuReadXmlSchema_Click(object sender, System.EventArgs e) { ClearForm(); if(openFileDialog1.ShowDialog() == DialogResult.OK) { dsTour.ReadXmlSchema(openFileDialog1.FileName); dataGrid1.DataSource = dsTour; FileStream filestream= File.Open(openFileDialog1.FileName, FileMode.Open, FileAccess.Read); //Проверяем, открыт ли поток, и если открыт, выполняем условие if(filestream != null) { //Создаем объект streamreader и связываем его с потоком filestream StreamReader streamreader = new StreamReader(filestream); //Считываем весь файл и записываем его в TextBox richTextBox1.Text = streamreader.ReadToEnd(); //Закрываем поток. filestream.Close(); } } }

Последнее, что нам осталось сделать, - привязать обработчиков пунктов меню группы "Открыть" к обработчику пункта "Auto":



public Form1() { InitializeComponent(); //Открытие this.mnuDiffGram.Click += new EventHandler(mnuAuto_Click); this.mnuFragment.Click += new EventHandler(mnuAuto_Click); this.mnuIgnoreSchema.Click += new EventHandler(mnuAuto_Click); this.mnuInferSchema.Click += new EventHandler(mnuAuto_Click); this.mnuReadSchema.Click += new EventHandler(mnuAuto_Click); }

Запускаем приложение. Для его тестирования можно воспользоваться содержимым папки XSD (рис. 11.28):


Рис. 11.28.  Приложение TypedDataSetReadXML. А - загрузка данных из базы, Б - открытие файла XMLTourFull.xml, В - открытие схемы XMLTourFull.xsd

Мы не добавляли обработку исключений, поэтому в ходе тестирования могут возникать ошибки. Добавьте ее самостоятельно для обработчиков пунктов меню "Открыть" и "Открыть схему".

В программном обеспечении к курсу вы найдете приложение TypedData SetReadXML (Code\Glava5\ TypedDataSetReadXML).


Содержание раздела