Опубликован: 05.08.2007 | Доступ: свободный | Студентов: 2201 / 83 | Оценка: 4.47 / 4.09 | Длительность: 20:11:00
ISBN: 978-5-9556-0097-0
Лекция 11:

Типизированный объект DataSet. Чтение и запись XML-документов

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

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

 Перегруженный метод ReadXml

увеличить изображение
Рис. 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Здесь и далее используются просто невероятно длинные названия проектов. Я решил, что название "TypedDataSetReadXML" будет более понятным, чем, например, "TDSRXML" или "TDSRX". Впрочем, вы можете называть свои проекты как вам угодно. ". Открываем проект, перетаскиваем на форму элемент управления MainMenu и создаем следующие пункты (рис. 11.27):

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

Рис. 11.27. Пункты главного меню приложения TypedDataSetReadXML
Name Text
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):

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

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

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

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