Meng Xianhui
Debido a la verdadera independencia de plataforma de XML (lenguaje de marcado extensible: lenguaje de marcado extensible), se está convirtiendo gradualmente en el principal medio de transmisión de datos. XML es un lenguaje de autodescripción y los datos en sí ya contienen metadatos, es decir, información sobre los datos en sí. Por ejemplo: "Mencius Capítulo E 1757281793923net_lover1807581793923" Es difícil ver lo que significa literalmente este conjunto de datos y no está claro en cuántos segmentos de datos se compone. Sin embargo, si usamos XML para describirlo de la siguiente manera, puedo ver claramente El significado de cada segmento de datos:
<DatosPersona>
<Persona>
<Nombre>Mencio Capítulo E</Nombre>
<Altura>175</Altura>
<Peso>72</Peso>
<Tel>81793923</Tel>
</Persona>
<Persona>
<nombre>net_lover</nombre>
<Altura>180</Altura>
<Peso>75</Peso>
<Tel>81793923</Tel>
</Persona>
</DatosPersona>
A partir del fragmento de XML anterior, no solo podemos ver claramente qué representa cada dato, sino también saber dónde se dividen los datos. En nuestras aplicaciones habituales, los resultados que obtenemos pueden estar en forma de matrices, colecciones o conjuntos de registros. ¿Cómo los convertimos en datos en formato XML autodescriptivo? Desde el punto de vista del formulario de datos, XML es un formato de texto simple de cadenas puras. Las cadenas son muy simples, rápidas y fáciles de transferir. Las matrices a veces son muy lentas para transferir por referencia y son muy problemáticas de procesar y recopilar. Los conjuntos son objetos, lo que provocará una disminución en el rendimiento de la computadora durante el procesamiento, y estos objetos están asociados con una plataforma específica, lo que requiere que la plataforma tenga un mecanismo de procesamiento incorporado para manejar las operaciones de los objetos. XML ya es un estándar del W3C y es independiente de la plataforma. El único requisito para nuestras computadoras es poder procesar cadenas XML simples, es decir, un analizador XML que pueda analizar cadenas XML y descomponer datos fácilmente en una interfaz. segmentos de datos independientes para que podamos acceder a ellos. Los analizadores XML son pequeños, potentes y se pueden encontrar en todas las plataformas. Una vez que recibimos los datos XML y los analizamos al estilo del ejemplo anterior, podemos convertirlos en diferentes representaciones a través de XSLT (eXstensible Stylesheet Language Transformations). El uso del formato de datos XML para la transmisión de datos hará que nuestro trabajo de escribir el código de la aplicación sea más simple y fácil, y tendrá una buena escalabilidad.
A continuación, echemos un vistazo a cómo convertir nuestros datos. Nuestro ejemplo está escrito en Microsoft Windows 2000, IIS5, MSXML3 y ADO2.6. Los datos de muestra utilizan la base de datos de muestra Northwind que viene con Microsoft SQL Server7.0. La razón por la que utilizamos SQL Server7 en lugar de SQL Server2000 que admite XML es para considerar el principio de universalidad. Nuestro propósito es procesar los conjuntos de registros obtenidos de diferentes tipos de fuentes de datos, no solo admitir la salida XML como la fuente de datos de SQL Server2000. . Utilice ADO porque tiene varios formatos y puede manejar diferentes tipos de fuentes de datos; utilice XML porque puede transmitir y analizar rápidamente. Pero el método de procesamiento en este ejemplo también es adecuado para cualquier entorno con el analizador XML de Microsoft, ADO2.5 o versión superior de Windows, IIS, SQL Server.
Para simplificar, solo seleccionamos productos cuyo precio unitario sea menor o igual a 20 dólares estadounidenses, cuyo inventario sea mayor o igual a 20 dólares estadounidenses y cuyo nombre de producto tenga menos o igual a 6 caracteres:
<%
Dim objRecordset
Establecer objRecordset = Server.CreateObject("ADODB.Recordset")
objRecordset.open _
"SELECCIONE Nombre del producto, Precio unitario, Unidades en stock" _
& "DE Productos" _
& "DONDE PrecioUnitario <= 20 " _
& "Y Unidades en stock >= 20 " _
& "Y LEN(NombreProducto) <= 6 " _
& "ORDENAR POR Nombre Del Producto", _
"Proveedor=SQLOLEDB;" _
& "Fuente de datos=AlgúnServidorSQL;" _
& "Catálogo inicial=Northwind;" _
& "ID de usuario=Mi nombre de usuario;" _
& "Contraseña=MiContraseña;"
%>
Ahora, utilizamos 3 métodos para convertir el conjunto de registros que obtuvimos al formato XML.
Primero, podemos recorrer todo el conjunto de registros, usar XML DOM (modelo de objetos de documento) y construir un árbol de nodos XML:
<%
Atenuar objXMLDOM, objRootNode, objNode
Establecer objXMLDOM = Server.CreateObject("MSXML2.DOMDocument")
Establecer objRootNode = objXMLDOM.createElement("xml")
objXMLDOM.documentElement = objRootNode
Hacer mientras NO objRecordset.EOF
Establecer objRowNode = objXMLDOM.createElement("fila")
Establecer objNode = objXMLDOM.createElement("ProductName")
objNode.text = objRecordset.Fields.Item("ProductName").Valor
objRowNode.appendChild(objNode)
Establecer objNode = objXMLDOM.createElement("PrecioUnitario")
objNode.text = objRecordset.Fields.Item("PrecioUnitario").Valor
objRowNode.appendChild(objNode)
Establecer objNode = objXMLDOM.createElement("UnitsInStock")
objNode.text = objRecordset.Fields.Item("Unidades en stock").Valor
objRowNode.appendChild(objNode)
objRootNode.appendChild(objRowNode)
objRecordset.MoveNext
Bucle
Establecer objNode = Nada
Establecer objRowNode = Nada
Establecer objRootNode = Nada
Establecer objRecordset = Nada
%>
Ahora tenemos un objeto DOM XML. El rendimiento de este método no es ideal cuando el conjunto de registros es grande, porque el objeto del conjunto de registros ADO y el objeto XML DOM deben almacenarse en la memoria del sistema al mismo tiempo.
El segundo método consiste en recorrer el conjunto de registros y generar directamente la cadena XML:
<%
Dim strXML
strXML = "<xml>"
objRecordset.MoveFirst
Hacer mientras NO objRecordset.EOF
strXML = strXML & "<fila>"
strXML = strXML & "<NombreProducto>" _
& objRecordset.Fields.Item("ProductName").Valor _
& "</ProductName>"
strXML = strXML & "<Precio unitario>" _
& objRecordset.Fields.Item("PrecioUnitario").Valor _
& "</PrecioUnitario>"
strXML = strXML & "<Unidades en stock>" _
& objRecordset.Fields.Item("Unidades en stock").Valor _
& "</UnidadesEnStock>"
strXML = strXML & "</row>"
objRecordset.MoveNext
Bucle
strXML = strXML & "</xml>"
Establecer objRecordset = Nada
%>
Sin embargo, el mayor defecto de los dos métodos anteriores es que el código no se puede reutilizar. Hemos escrito los nombres de los nodos. Si consultamos diferentes campos, también debemos cambiar manualmente nuestro código para satisfacer las necesidades de los diferentes nodos. Nuestro enfoque a continuación será más general.
El tercer método: método reutilizable.
<%
Dim strXML
strXML = "<xml>"
objRecordset.MoveFirst
Hacer mientras NO objRecordset.EOF
strXML = strXML & "<fila>"
Para cada varItem en objRecordset.Fields
strXML = strXML _
& "<" & varItem.name & ">" _
&varItem.valor_
& "</" & varItem.nombre & ">"
Próximo
strXML = strXML & "</row>"
objRecordset.MoveNext
Bucle
strXML = strXML & "</xml>"
Establecer objRecordset = Nada
%>
Un método más eficaz es utilizar directamente el método de guardar integrado del conjunto de registros, que puede convertir automáticamente el contenido del conjunto de registros al formato XML. Después de llamar al método de guardar, podemos liberar inmediatamente la instancia del objeto del conjunto de registros en la memoria. . El método de guardar tiene dos parámetros: uno es el lugar donde se guardará el XML y el otro es un indicador que indica el formato en el que se guardan los datos. Podemos guardar los datos como un objeto DOM XML (objeto ADO STREAM) o guardarlos directamente como un objeto ASP RESPONSE. Por razones de generalidad, los guardamos como un DOM XML y usamos la constante ADO adPersistXML para el segundo parámetro. . He aquí cómo:
<%
Const adPersistXML = 1
objXMLDOM tenue
Establecer objXMLDOM = Server.CreateObject("MSXML2.DOMDocument.3.0")
objRecordset.save objXMLDOM, adPersistXML
Establecer objRecordset = Nada
%>
Este método es conveniente, rápido y está libre de errores. No es necesario cambiar manualmente el nombre del nodo para diferentes consultas. Sin embargo, el XML producido por este método no es lo suficientemente conciso. Mire el resultado que produce:
<xml
xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs="urna:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
<s:ElementType
nombre="fila"
contenido="eltOnly"
rs:CommandTimeout="30">
<s:Tipo de atributo
nombre = "Nombre del producto"
rs:número="1"
rs:writeunknown="true">
<s:tipo de datos
dt:tipo="cadena"
dt:maxLength="40"
rs:maybenull="falso"/>
</s:TipoAtributo>
<s:TipoAtributo
nombre="Precio unitario"
rs:número="2"
rs:nullable="verdadero"
rs:writeunknown="true">
<s:tipo de datos
dt:tipo="número"
rs:dbtype="moneda"
dt:longitudmax="8"
rs:precisión="19"
rs: longitud fija = "verdadero" />
</s:TipoAtributo>
<s:TipoAtributo
nombre="Unidades en stock"
rs:número="3"
rs:nullable="verdadero"
rs:writeunknown="true">
<s:tipo de datos
dt:tipo="i2"
dt:longitudmax="2"
rs:precisión="5"
rs: longitud fija = "verdadero" />
</s:AttributeType>
<s:extends type="rs:rowbase"/>
</s:ElementType>
</s:Schema>
<rs:data>
<z:row
Nombre del producto="Chai"
PrecioUnitario="18"
Unidades en stock="39"/>
<z:fila
NombreProducto="Konbu"
PrecioUnitario="6"
Unidades en stock="24"/>
<z:fila
NombreProducto="Tofu"
PrecioUnitario="23.25"
UnitsInStock="35"/>
</rs:data>
</xml>
El XML generado automáticamente por ADO contiene información de esquema, que describe qué nodos y atributos están permitidos en este XML y qué tipos de datos se utilizan, y los nodos de datos son También aumentó el espacio de nombres. La información del esquema puede ser útil cuando se requiere validación de datos o para procesamientos más complejos, pero, en la mayoría de los casos, utilizamos clientes ligeros y no necesitamos información del esquema. Podemos usar XSLT para separar la información que queremos y eliminar la información redundante. Por tanto, escribimos el siguiente "DataCleaner.xsl":
<?xml versión="1.0"?>
<xsl:versión de hoja de estilo="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="urna:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
<xsl:salida omitir-xml-declaración="sí"/>
<xsl:coincidencia de plantilla="/">
<xsl:nombre del elemento="xml">
<xsl:for-each select="/xml/rs:data/z:row">
<xsl:nombre del elemento="fila">
<xsl:para-cada seleccionar="@*">
<xsl:elemento nombre="{nombre()}">
<xsl:valor-de selección="."/>
</xsl:elemento>
</xsl:para-cada>
</xsl:elemento>
</xsl:para-cada>
</xsl:elemento>
</xsl:plantilla>
</xsl:hoja de estilo>
Este XSLT tiene características reutilizables y es aplicable a diferentes resultados de consultas. El siguiente es un ejemplo de cómo utilizar este XSLT:
<%
Dim strCleanXML, objXMLDOM_XSLT
Establecer objXMLDOM_XSLT = CreateObject("MSXML2.DOMDocument")
objXMLDOM_XSLT.load(Server.MapPath("DataCleaner.xsl"))
strCleanXML = objXMLDOM.transformNode(objXMLDOM_XSLT)
Establecer objXMLDOM = Nada
Establecer objXMLDOM_XSLT = Nada
%>
Después del procesamiento anterior, strClaenXML es la cadena XML que queremos.
<xml>
<fila>
<ProductName>Chai</ProductName>
<PrecioUnitario>18</PrecioUnitario>
<UnidadesEnStock>39</UnidadesEnStock>
</fila>
<fila>
<ProductName>Konbu</ProductName>
<PrecioUnitario>6</PrecioUnitario>
<UnidadesEnStock>24</UnidadesEnStock>
</fila>
</xml>
La cadena XML en el formato anterior es el estilo de conjunto de nodos que vemos a menudo. Si no desea procesar el campo en un nodo, sino procesarlo en un nodo de atributo, solo necesitamos realizar pequeños cambios en DataCleaber. xsl:
<?xml versión="1.0"?>
<xsl:versión de hoja de estilo="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="urna:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
<xsl:salida omitir-xml-declaración="sí"/>
<xsl:coincidencia de plantilla="/">
<xsl:nombre del elemento="xml">
<xsl:for-each select="/xml/rs:data/z:row">
<xsl:nombre del elemento="fila">
<xsl:para-cada seleccionar="@*">
<xsl:nombre del atributo="{nombre()}">
<xsl:valor-de selección="."/>
</xsl:atributo>
</xsl:para-cada>
</xsl:elemento>
</xsl:para-cada>
</xsl:elemento>
</xsl:plantilla>
</xsl:hoja de estilo>
El siguiente es el resultado del uso del nuevo estilo, que es mucho más corto que usar nodos para representar la longitud del campo. La velocidad de transferencia será más rápida:
<xml>
<fila NombreProducto="Chai" PrecioUnitario="18" UnidadesEnStock="39"/>
<fila NombreProducto="Konbu" PrecioUnidad="6" UnidadesEnStock="24"/>
</xml>
Hasta ahora, hemos introducido varias formas de obtener datos en formato XML de conjuntos de registros ADO y también hemos obtenido la cadena más simplificada. Pero hay varias cuestiones a las que aún debes prestar atención. Algunos valores de campo tienen caracteres que no son compatibles con XML, como: "'< >&, como el nombre de P&G Procter & Gamble, el nombre de. Producto Gumbo Mix del Chef Anton, etc. Debe hacer esto al convertir. Llevar a cabo el procesamiento de codificación. Hay cuestiones a tener en cuenta al utilizar el método de guardar en Microsoft ADO 2.6 SDK: 1. El método de guardar solo funciona en conjuntos de registros abiertos. con campos de tipos adVariant, adIDispatch y adIUnknown no se admiten savw; 3. Existen dos limitaciones al guardar conjuntos de registros jerárquicos (formas de datos): las parametrizaciones y los conjuntos de registros que contienen actualizaciones no resueltas no se pueden guardar.
Para mejorar aún más el rendimiento, puede colocar el trabajo de conversión en componentes COM/COM+ y el código ASP solo realiza la presentación final de los datos. Separe la capa empresarial, la capa de datos y la capa de presentación. ASP solo necesita llamar al componente de datos. El componente de datos llama al procedimiento almacenado de la base de datos, convierte el resultado a XML y, finalmente, solo envía la cadena XML simple al programa ASP. y ASP puede usar XSLT para convertir el XML y enviar el resultado al navegador.