Протокол HTTP. Запрос и получение XML данных

Протокол HTTP (англ. HyperText Transfer Protocol — «протокол передачи гипертекста») позволяет обмениваться текстовой и другой символьной информацией. В настоящее время используется для передачи произвольных данных по схеме запрос-ответ. Основным назначением протокола HTTP является передача веб-страниц (текстовых файлов с специальной разметкой, HTML, XML, CSS и др.), в нашем случае речь идет о запросе и получении xml файлов.

Silverlight является мощной платформой для разработки захватывающих интерактивных приложений для Интернет, настольных компьютеров и мобильных устройств, в режиме онлайн или офлайн. Включает в себя модуль для браузера, который позволяет запускать приложения, содержащие анимацию, векторную графику и аудио-видео ролики, значительно расширяя графические возможности браузеров. Создавая красочные интернет-приложения удобно поддерживать информационную связь с сервером посредством xml файлов.

XML (eXtensible Markup Language) - расширяемый язык разметки, строго структурированное текстовое произведение. XML имеет иерархическую структуру и обязательно начинается с главного и единственного тега называемого корневым узлом. В корневой узел же может вложено любое количество элементов и групп элементов. Каждый отдельный элемент заключается в тег, структура xml файла обеспечивает однозначный доступ к единице информации по определенным признакам. В качестве признаков могут выступать название элемента, его путь, его атрибуты.

Листинг №1 Пример структуры XML


	Производство автомобилей
	тыс. шт.
	
		
			2006
			1340
		
		
			2007
			1200
		
		
			2008
			2200
		
		
			2009
			3430
		
		
			2010
			4000
		
	

Приложение Silverlight может использовать xml данные для построения пользовательского интерфейса. Например сервер может обрабатывать и хранить данные полученные с нескольких ресурсов, а приложение Silverlight запрашивать сохраненные данные выдавая красочную визуальную информацию пользователю. Чтобы экономить вычислительные ресурсы сервера можно на сервере хранить только базовые данные, а большую часть вычислений производить на машине клиента. В прикрепленных ниже исходниках примеры использования дружелюбного протокола HTTP для запроса данных в xml форме.

Для выполнения запроса по протоколу HTTP данных в форме xml Silverlight предлагает высокоуровневые классы WebClient и HttpWebRequest. Оба класса имеют асинхронные методы запроса, не блокирующие пользовательский интерфейс.

Самая простая реализация работы с HTTP это класс WebClient. Чтобы получить содержимое файла xml с сервера предлагаются интуитивно понятные асинхронные методы DownloadStringAsync(), OpenReadAsync() в сочетании с событиями окончания запроса соответственно OnDownloadStringCompleted(), OnOpenReadCompleted(). Метод DownloadStringAsync(), как и видно из названия, начинает загрузку строковых данных, результат можно в событии OnDownloadStringCompleted(). OpenReadAsync() предназначен для получения входного потока в соответствующем тандемном событии OnOpenReadCompleted(). Очень удобно, что класс WebClient переключает события завершения запросов из дополнительных потоков в контекст пользователя, не требуя подключения делегатов, т. е. события OnDownloadStringCompleted() и OnOpenReadCompleted() всегда вызывается в потоке пользовательского интерфейса.

Листинг №2 Исходный код на классе WebClient

private void Button_ClickGraphAvto(object sender, RoutedEventArgs e)
{
	divider = 20;
	_webClient.OpenReadAsync(new Uri(_urlRequest + "?req=avto"));
}

. . . . . . . . . . . .

void _webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
	try
	{
		// Получаем полную строку ответа
		StreamReader sr = new StreamReader(e.Result);
		string strXml = sr.ReadToEnd();

		ShowString(strXml);
		ShowGraph(e.Result);
	}
	catch(Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
}

Класс HttpWebRequest предоставляет для запроса и получения файла xml следующие методы работы: запроса BeginGetResponse() и получения результата EndGetResponse(). Приложениям Silverlight нет смысла использовать синхронные методы и соответственно HttpWebRequest имеет только асинхронную функциональность. Но, в отличие от WebClient, асинхронка HttpWebRequest работает в дополнительных потоках. Чтобы корректно получить доступ к результатам запроса необходимо использовать делегаты и диспетчерскую службу System.Windows.Threading.Dispatcher.

Листинг №3 Исходный код на классе HttpWebRequest

private void Button_ClickGraphAvto(object sender, RoutedEventArgs e)
{
	divider = 20;
	HttpWebRequest ht = (HttpWebRequest)HttpWebRequest.Create(_urlRequest + "?req=avto");
	IAsyncResult result = ht.BeginGetResponse(new AsyncCallback(RespCallbackXml), ht);
}

// Асинхронный обработчик веб запроса 
private void RespCallbackXml(IAsyncResult asynchronousResult)
{
	// Это место принадлежит вспомогательному потоку, 
	// отличному от пользовательского интерфейса.

	try
	{
		// Извлекаем ответы от наших запросов в виде потока
		HttpWebRequest ht = (HttpWebRequest)asynchronousResult.AsyncState;
		HttpWebResponse response = (HttpWebResponse)ht.EndGetResponse(asynchronousResult);

		Stream responseStream = response.GetResponseStream();
		responseStream.Position = 0;


		// Получаем полную строку из полученного потока
		StreamReader sr = new StreamReader(responseStream);
		string strXml = sr.ReadToEnd();
		ShowString(strXml);

		// Передаем поток данных на обработку xml тегов
		ShowGraph(responseStream);

	}
	catch(Exception e)
	{
		// Исключения WebRequest гораздо информативней, чем
		// исключения класса WebClient.
		ShowString(e.Message);
	}
}

Они оба класса хороши для выполнения запросов xml данных, хотя, для запросов, проще использовать более высокоуровневый класс WebClient. HttpWebRequest обладает большей функциональностью, более понятной работой исключений, но сложнее в использовании. Выбор зависит от степени сложности построения http запросов. Не подошел один класс, никто не запрещает использовать другой.

Для обработки входного потока xml данных в исходнике применяется скоростной XmlReader. Данный класс характеризуется высокой скоростью чтения xml документов. XmlReader читает данные непосредственно с потока, читает только вперед: прочитав элемент, указатель мгновенно перемещается на следующий. Чтобы эффективно использовать XmlReader для своего приложения необходимо точно знать xml структуру исследуемого файла. В исходниках использованы 3 идентичных по структуре файла статистических данных.

Листинг №4 Обработка полученного xml файла

// Читаем и разбираем xml файл.
// Читаем только значащие для нас элементы.
// Каждый этап чтения перемещает нас к следующему xml тегу.
// Нельзя более одного раза прочитать один и тот же тег.
// Оператор using гарантирует высвобождение памяти после окончания работы XmlReader.
using (XmlReader xmlReader = XmlReader.Create(stream))
{
    int countRect = 0;
	int countY = 0;
	int countN = 0;
	while (xmlReader.Read() == true)
	{
		if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "info")
		{
			// Прочитав параметр, указатель автоматически перемещается к концу элемента.
			// Несколько вызовов ReadElementContentAsString() позволяют перемещаться от 
			// одного xml тега к следующему.
			LabelHeader.Content = xmlReader.ReadElementContentAsString();
		}

		if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "unit")
		{
			// Получаем единицы измерения
			LabelUnit.Content = "в " + xmlReader.ReadElementContentAsString();
		}

		if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "name")
		{
			// Получаем года статистики производств.
			// Любое чтение перемещает нас к следующему xml тегу.
			_labelsYears[countY].Content = xmlReader.ReadInnerXml() + "г.";
			countY++;
		}

		if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "number")
		{
			// Получение и обработка статистики

			string s = xmlReader.ReadInnerXml();
			double value = double.Parse(s);

			// Расчет высоты прямоугольника визуализации единицы объема производства
			_rectangles[countRect].Height = value / divider;

			// Вывод величин объемов производства
			_labelsNumbers[countN].Content = s;

			// Расчет положения строковой метки объема над прямоугольником визуализации.
			// Для свойства HorizontalAlignment="Center" margin.left и margin.right должны быть одинаковы 
			// но противоположного знака.
			Thickness t = _rectangles[countRect].Margin;
			double delta = G1.ActualWidth / 2 - _labelsNumbers[countN].ActualWidth / 2;
			_labelsNumbers[countN].Margin = new Thickness(-delta + t.Left, 50, 
											delta - t.Left, t.Bottom + _rectangles[countRect].Height + 5);

			// Счетчики элементов массивов прямоугольников и метки
			countRect++;
			countN++;
		}

   }// while(xmlReader.Read() == true)
}// using (XmlReader xmlReader = XmlReader.Create(stream))

Исходники прикрепленные ниже содержат полные проекты веб-сайтов для работы с запросами, получением и разбором данных в форме xml. В одном проекте используется класс HttpWebRequest, в другом WebClient. Значимые строки кода подробно комментированы. Исходные коды созданы в среде программирования MS Visual Studio 2013 и протестированы в Visual Studio 2013 Express.

Просмотр демостраницы »

Файл исходника Размер Количество загрузок
silverlightrequestxml.zip 360 КБайт 232
Яндекс цитирования Rambler's Top100 Яндекс.Метрика