Мэн Сяньхуэй
Благодаря истинной платформенной независимости XML (расширяемый язык разметки: расширяемый язык разметки) он постепенно становится основным средством передачи данных. XML — это язык самоописания, и сами данные уже содержат метаданные, то есть информацию о самих данных. Например: «Mencius Chapter E 1757281793923net_lover1807581793923». Этот набор данных трудно понять, что он означает буквально, и неясно, из скольких сегментов данных он состоит. Однако, если мы используем XML для его описания следующим образом, мы можно ясно видеть значение каждого сегмента данных:
<ПерсонаДанные>
<Человек>
<Name>Мэн-цзы, Глава E</Name>
<Высота>175</Высота>
<Вес>72</Вес>
<Тел.>81793923</Тел.>
</Человек>
<Человек>
<name>net_lover</name>
<Высота>180</Высота>
<Вес>75</Вес>
<Тел.>81793923</Тел.>
</Человек>
</ПерсонаДанные>
Из приведенного выше фрагмента XML мы можем не только четко видеть, что представляют собой каждые данные, но также знать, где данные разделены. В наших обычных приложениях результаты, которые мы получаем, могут быть в форме массивов, коллекций или наборов записей. Как нам преобразовать их в данные формата XML с самоописанием? С точки зрения формы данных XML представляет собой простой текстовый формат чистых строк. Строки очень просты, быстры и легко передаются. Массивы иногда очень медленно передаются по ссылке и их очень сложно обрабатывать, а также собирать и записывать. оба набора являются объектами, что приведет к снижению производительности компьютера во время обработки, и эти объекты связаны с определенной платформой, что требует, чтобы платформа имела встроенный механизм обработки для обработки операций с объектами. XML уже является стандартом W3C и не зависит от платформы. Единственное требование к нашим компьютерам — это возможность обрабатывать простые строки XML, то есть синтаксический анализатор XML может анализировать строки XML и легко разлагать данные через интерфейс. независимые сегменты данных, чтобы мы могли получить к ним доступ. Анализаторы XML небольшие, производительные и их можно найти на любой платформе. Как только мы получим данные XML и проанализируем их в стиле приведенного выше примера, мы сможем преобразовать их в различные представления с помощью XSLT (преобразования расширяемого языка таблиц стилей). Использование формата данных XML для передачи данных сделает нашу работу по написанию кода приложения более простой и легкой, а также обеспечит хорошую масштабируемость.
Далее давайте посмотрим, как преобразовать наши данные. Наш пример написан под Microsoft Windows 2000, IIS5, MSXML3 и ADO2.6. В примере данных используется образец базы данных Northwind, поставляемый с Microsoft SQL Server7.0. Причина, по которой мы используем SQL Server7 вместо SQL Server2000, поддерживающего XML, заключается в учете принципа универсальности. Наша цель — обрабатывать наборы записей, полученные из разных типов источников данных, а не просто поддерживать вывод XML, как источник данных SQL Server2000. . Используйте ADO, потому что он имеет различные формы и может обрабатывать разные типы источников данных. Используйте XML, потому что он может быстро передавать и анализировать. Но метод обработки в этом примере также подходит для любой среды с синтаксическим анализатором Microsoft XML, ADO2.5 или более поздней версии Windows, IIS, SQL Server.
Для простоты мы выбираем только те продукты, цена за единицу которых меньше или равна 20 долларам США, запасы которых больше или равны 20 долларам США и название продукта которых меньше или равно 6 символам:
<%
Тусклый объект objRecordset
Set objRecordset = Server.CreateObject("ADODB.Recordset")
objRecordset.open _
«ВЫБЕРИТЕ Имя продукта, Цена за единицу, Единицы на складе» _
& «ИЗ ПРОДУКТОВ» _
& "ГДЕ UnitPrice <= 20" _
& "И ЕдиницНаСкладе >= 20" _
& "И ЛЕН(ИмяПродукта) <= 6" _
& «ЗАКАЗАТЬ ПО НАЗВАНИЮ ПРОДУКТА», _
"Поставщик=SQLOLEDB;" _
& "Источник данных=SomeSQLServer;"
& "Исходный каталог=Северный ветер;"
& "Идентификатор пользователя=MyUserName;"
& "Пароль=МойПароль;"
%>
Теперь мы используем 3 метода для преобразования полученного набора записей в формат XML.
Во-первых, мы можем просмотреть весь набор записей, использовать XML DOM (объектную модель документа) и построить дерево узлов XML:
<%
Тусклый objXMLDOM, objRootNode, objNode
Установите objXMLDOM = Server.CreateObject("MSXML2.DOMDocument")
Установите objRootNode = objXMLDOM.createElement("xml")
objXMLDOM.documentElement = objRootNode
Делайте, пока НЕ objRecordset.EOF
Установите objRowNode = objXMLDOM.createElement("строка")
Установите objNode = objXMLDOM.createElement("ProductName")
objNode.text = objRecordset.Fields.Item("ИмяПродукта").Значение
objRowNode.appendChild(objNode)
Установите objNode = objXMLDOM.createElement("UnitPrice")
objNode.text = objRecordset.Fields.Item("UnitPrice").Value
objRowNode.appendChild(objNode)
Установите objNode = objXMLDOM.createElement("UnitsInStock")
objNode.text = objRecordset.Fields.Item("UnitsInStock").Value
objRowNode.appendChild(objNode)
objRootNode.appendChild(objRowNode)
objRecordset.MoveNext
Петля
Установить objNode = Ничего
Установить objRowNode = Ничего
Установить objRootNode = Ничего
Установить objRecordset = Ничего
%>
Теперь у нас есть объект XML DOM. Производительность этого метода не идеальна, если набор записей большой, поскольку объект набора записей ADO и объект XML DOM должны храниться в системной памяти одновременно.
Второй метод — просмотреть набор записей и напрямую сгенерировать саму строку XML:
<%
Тусклый стрXML
стрXML = "<xml>"
objRecordset.MoveFirst
Делайте, пока НЕ objRecordset.EOF
strXML = strXML & "<строка>"
strXML = strXML & "<ProductName>" _
& objRecordset.Fields.Item("ProductName").Value _
& "</ProductName>"
strXML = strXML & "<UnitPrice>" _
& objRecordset.Fields.Item("UnitPrice").Value _
& "</UnitPrice>"
strXML = strXML & "<UnitsInStock>" _
& objRecordset.Fields.Item("UnitsInStock").Value _
& "</UnitsInStock>"
strXML = strXML & "</row>"
objRecordset.MoveNext
Петля
стрXML = стрXML & "</xml>"
Установить objRecordset = Ничего
%>
Однако самый большой недостаток двух вышеупомянутых методов заключается в том, что код нельзя использовать повторно. Мы записали имена узлов. Если мы запрашиваем разные поля, нам также придется вручную изменять наш код, чтобы удовлетворить потребности разных узлов. Наш подход ниже станет более общим.
Третий метод: многоразовый метод.
<%
Тусклый стрXML
стрXML = "<xml>"
objRecordset.MoveFirst
Делайте, пока НЕ objRecordset.EOF
strXML = strXML & "<строка>"
Для каждого varItem в objRecordset.Fields
стрXML = стрXML _
& "<" & varItem.name & ">" _
&varItem.value_
& "</" & varItem.name & ">"
Следующий
strXML = strXML & "</row>"
objRecordset.MoveNext
Петля
стрXML = стрXML & "</xml>"
Установить objRecordset = Ничего
%>
Более эффективный метод — напрямую использовать встроенный метод сохранения набора записей, который может автоматически преобразовать содержимое набора записей в формат XML. После вызова метода сохранения мы можем немедленно освободить экземпляр объекта набора записей в памяти. . Метод save имеет два параметра: один — это место, где должен быть сохранен XML, а другой — индикатор, указывающий формат, в котором сохраняются данные. Мы можем сохранить данные как объект XML DOM (объект ADO STREAM) или напрямую сохранить их как объект ASP RESPONSE. Для общности мы сохраняем их как XML DOM и используем константу ADO adPersistXML в качестве второго параметра. . Вот как:
<%
Константа adPersistXML = 1
Тусклый объект objXMLDOM
Установите objXMLDOM = Server.CreateObject("MSXML2.DOMDocument.3.0")
objRecordset.save objXMLDOM, adPersistXML
Установить objRecordset = Ничего
%>
Этот метод удобен, быстр и безошибочен. Нет необходимости вручную менять имя узла для разных запросов. Однако XML, создаваемый этим методом, недостаточно краток. Взгляните на результат:
<xml
xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs="urn:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
<s:ElementType
имя="строка"
контент="eltOnly"
rs:CommandTimeout="30">
<s:AttributeType
name="ИмяПродукта"
rs:number="1"
rs:writeunknown="true">
<s:datatype
дт:тип="строка"
дт:maxLength="40"
rs:maybenull="false"/>
</s:AttributeType>
<s:AttributeType
name="Единичная цена"
rs:number="2"
rs:nullable="истина"
rs:writeunknown="true">
<s:datatype
дт:тип="число"
rs:dbtype="валюта"
дт:maxLength="8"
rs:precision="19"
rs:fixedlength="true"/>
</s:AttributeType>
<s:AttributeType
name="Единицы в наличии"
rs:number="3"
rs:nullable="истина"
rs:writeunknown="true">
<s:datatype
дт:тип="i2"
дт:maxLength="2"
rs:precision="5"
rs:fixedlength="true"/>
</s:AttributeType>
<s:extends type="rs:rowbase"/>
</s:ElementType>
</s:Schema>
<rs:data>
<z:row
ProductName="Чай"
UnitPrice="18"
UnitsInStock="39"/>
<z:row
ProductName="Конбу"
ЕдиницаЦена="6"
UnitsInStock="24"/>
<z:row
ProductName="Тофу"
UnitPrice="23,25"
UnitsInStock="35"/>
</rs:data>
</xml>
XML, автоматически сгенерированный ADO, содержит информацию о схеме, которая описывает, какие узлы и атрибуты разрешены в этом XML и какие типы данных используются, а узлы данных также увеличено пространство имен. Информация о схеме может быть полезна там, где требуется проверка данных или для более сложной обработки, но в большинстве случаев мы используем тонкие клиенты и нам не нужна информация о схеме. Мы можем использовать XSLT, чтобы выделить нужную информацию и удалить избыточную информацию. Поэтому пишем такой «DataCleaner.xsl»:
<?xml версия="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl=" http://www.w3.org/1999/XSL/Transform "
xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs="urn:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:имя элемента="xml">
<xsl:for-each select="/xml/rs:data/z:row">
<xsl:element name="row">
<xsl:for-each select="@*">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:шаблон>
</xsl:таблица стилей>
Этот XSLT имеет функции многократного использования и применим к различным результатам запроса. Ниже приведен пример использования этого XSLT.
<%
Тусклый strCleanXML, objXMLDOM_XSLT
Установите objXMLDOM_XSLT = CreateObject("MSXML2.DOMDocument")
objXMLDOM_XSLT.load(Server.MapPath("DataCleaner.xsl"))
strCleanXML = objXMLDOM.transformNode(objXMLDOM_XSLT)
Установить objXMLDOM = Ничего
Установить objXMLDOM_XSLT = Ничего
%>
После вышеуказанной обработки strClaenXML — это нужная нам XML-строка.
<xml>
<строка>
<ProductName>Чай</ProductName>
<UnitPrice>18</UnitPrice>
<UnitsInStock>39</UnitsInStock>
</строка>
<строка>
<ProductName>Конбу</ProductName>
<UnitPrice>6</UnitPrice>
<UnitsInStock>24</UnitsInStock>
</строка>
</xml>
Строка XML в приведенном выше формате — это стиль набора узлов, который мы часто видим. Если вы не хотите обрабатывать поле в узел, а превращать его в узел атрибута, то нам нужно лишь внести небольшие изменения в DataCleaber. xsl:
<?xml версия="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl=" http://www.w3.org/1999/XSL/Transform "
xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs="urn:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:имя элемента="xml">
<xsl:for-each select="/xml/rs:data/z:row">
<xsl:element name="row">
<xsl:for-each select="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:атрибут>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:шаблон>
</xsl:таблица стилей>
Ниже приведен результат использования нового стиля, который намного короче, чем использование узлов для представления длины поля. Скорость передачи будет выше:
<xml>
<row ProductName="Чай" UnitPrice="18" UnitsInStock="39"/>
<row ProductName="Konbu" UnitPrice="6" UnitsInStock="24"/>
</xml>
На данный момент мы представили несколько способов получения данных формата XML из наборов записей ADO, а также получили наиболее упрощенную строку. Но есть несколько проблем, на которые все же необходимо обратить внимание. Некоторые значения полей содержат символы, не поддерживаемые в XML, например: «'< >&, например имя P&G Procter & Gamble, имя компании. Продукт Chef Anton's Gumbo Mix и т. д. Это необходимо сделать при преобразовании. Выполните обработку кодирования. При использовании метода сохранения в Microsoft ADO 2.6 SDK следует учитывать следующие моменты: 1. Метод сохранения работает только с открытым набором записей. с полями типов adVariant, adIDispatch и adIUnknown не поддерживаются savw. 3. При сохранении иерархических наборов записей (форм данных) невозможно сохранить параметризации и наборы записей, содержащие неразрешенные обновления.
Чтобы еще больше повысить производительность, вы можете поместить работу по преобразованию в компоненты COM/COM+, а код ASP будет выполнять только окончательное представление данных. Разделите бизнес-уровень, уровень данных и уровень представления. ASP нужно только вызвать компонент данных. Компонент данных вызывает хранимую процедуру базы данных, преобразует результат в XML и, наконец, возвращает простую строку XML обратно в программу ASP. и ASP может использовать XSLT для преобразования XML и отправки результата в браузер.