Технология Ajax – передача структурированной информации
(форматы XML и JSON)
Передача простых текстовых данных, не требующих дальнейшего разбора и использующихся в том же виде, не представляет особых трудностей. Сложнее обработать ответ на запрос, который содержит структурированные данные, например, данные о заказе корзине покупателя Internet-магазина. Эти данные должны содержать название товара, заказанное количество, цена единицы товара и пр. В этом случае передача ответа в виде простого текста не представляется целесообразной и, если производится, то требует тщательной и непростой обработки на стороне браузера.
В таких ситуациях передачу данных от сервера браузеру производят в форматах XML или JSON (JavaScript Object Notation). Оба формата поддерживаются браузерами. XML-данные могут быть обработаны с помощью древовидного представления XML-документа – DOM. Второй формат JSON специфичен для применения в JavaScript и, в какой-то степени, легче обрабатывается на стороне браузера.
Разберем пример отсылки данных о товарах, их наличию на складе и ценах на них в формате XML. Код серверного aspx-сценария может быть таким:
using System;
using System. Data;
using System. Configuration;
using System. Collections;
using System. Web;
using System. Web. Security;
using System. Web. UI;
using System. Web. UI. WebControls;
using System. Web. UI. WebControls. WebParts;
using System. Web. UI. HtmlControls;
using System. Xml;
using System. IO;
using System. Data. OleDb;
public partial class Catalog : System. Web. UI. Page
{
protected void Page_Load(object sender, EventArgs e)
{
// обращение к базе данных для получения списка товаров
string ConnString = "Provider=SQLOLEDB;Data Source=AAA\\SQLEXPRESS;
Integrated Security=SSPI;Initial Catalog=shop";
OleDbConnection con = new OleDbConnection(ConnString);
con. Open();
OleDbCommand com = new OleDbCommand("select * from tovars", con);
OleDbDataReader dr = com. ExecuteReader();
// генерация XML-документа в виде текстовой строки (StringWriter)
StringWriter sw = new StringWriter();
XmlTextWriter xmlTR = new XmlTextWriter(sw);
xmlTR. WriteStartDocument();
// создание корневого элемента Catalog для списка всех товаров
xmlTR. WriteStartElement("Catalog");
while(dr. Read())
{
// создание элемента Tovar для каждого из товаров
xmlTR. WriteStartElement("Tovar");
// задание атрибутов для элемента Tovar –
// названия, кода, количества, цены
xmlTR. WriteAttributeString("name_tovar", ""+dr["name_tovar"]);
xmlTR. WriteAttributeString("id_tovar", "" + dr["id_tovar"]);
xmlTR. WriteAttributeString("count_tovar", ""+dr["count_tovar"]);
xmlTR. WriteAttributeString("price_tovar", "" + dr["price_tovar"]);
// закрытие элемента для товара
xmlTR. WriteEndElement();
}
// закрытие элемента для каталога товаров
xmlTR. WriteEndElement();
con. Close();
xmlTR. WriteEndDocument();
// отправка полученного каталога товаров в виде XML-документа
Response. AddHeader("Content-Type", "text/xml");
Response. Write(sw. ToString());
}
}
В результате будет получен примерно следующий XML-код:
<Catalog>
<Tovar name_tovar=”tovar1” id_tovar=”1” count_tovar=”10” price_tovar=”1000”/>
<Tovar name_tovar=”tovar2” id_tovar=”2” count_tovar=”1000” price_tovar=”100”/>
. . .
</Catalog>
На стороне браузера требуется данный XML-документ получить и обработать. Ответ будет получен с помощью свойства объекта передачи информации, который называется responseXML. Сохранив его значение в строковой переменной, можно потом осуществить его разбор с помощью применения модели DOM. В данной модели можно обращаться к элементам с помощью функции getElementsByTagName. Дочерние элементы доступны с помощью коллекции childNodes, к элементам которой можно обращаться как к элементам массива. Атрибуты элемента доступны с помощью коллекции attributes. Найти в ней значение атрибута по его имени можно с помощью функции getNamedItem с указанием имени атрибута. Например, сформировать html-таблицу с полученными данными можно с помощью следующей JavaScript-функции:
function printCatalog()
{
// получение html-панели, в которую будет вставлена таблица
var panel=document. getElementById('tablePanel');
var s="<table>";
// пусть catalog – переменная, которая хранит ответ в виде xml-документа
// array_tov – массив элементов типа Tovar
var array_tov=catalog. getElementsByTagName("Tovar");
for(var i=0;i<array_tov. length; i++)
{
// получение атрибутов товара и отображение их в столбцах таблицы
s+="<tr><td>"+array_tov[i].attributes. getNamedItem("name_tovar").text+
"</td>";
s+="<td>"+array_tov[i].attributes. getNamedItem("count_tovar").text+
"</td>";
s+="<td>"+array_tov[i].attributes. getNamedItem("price_tovar").text+
"</td></tr>";
}
s+="</table>";
// замена html-кода панели на сформированную таблицу
panel. innerHTML=s;
}
Заметим, что передача данных xml-вида из ashx-файла не дает возможности получения данных через свойство responseXML. В этом случае можно получить данные как текст, а затем на стороне клиента JavaScript-средствами создать xml-документ и загрузить его из полученной строки:
var xmlDoc=new ActiveX('Microsoft. XMLDOM');
xmlDoc. loadXML(httpRequester. responseText);
При использовании формата JSON должен быть сгенерирован следующий документ в текстовом формате:
{“tovars” : [
{“name_tovar” : “tovar1”, “id_tovar” : 1, “count_tovar” : 10,
“price_tovar” : 1000},
{“name_tovar” : “tovar2”, “id_tovar” : 2, “count_tovar” : 1000,
“price_tovar” : 100},
. . .
]};
Особенность формата JSON заключается в том, что к элементам данных можно обращаться напрямую по их именам как к свойствам объекта. JavaScript-код генерации таблицы с информацией о товарах примет следующий вид:
// получение json-данных в текстовом формате
// нужно заключить полученные данные в круглые скобки
var jsonData=eval('('+httpRequester. responseText+')');
var panel=document. getElementById('tablePanel');
var s="<table>";
// обращение к товарам как к массиву
for(var i=0; i<jsonData. tovars. length;i++)
s+="<tr><td>"+jsonData. tovars[i].name_tovar+"</td><td>"+
jsonData. tovars[i].count_tovar+"</td><td>"+
jsonData. tovars[i].price_tovar+"</td></tr>";
s+="</table>";
// замена html-кода панели на сформированную таблицу
panel. innerHTML=s;


