Meng Xianhui
Devido à verdadeira independência de plataforma do XML (Extensible Markup Language: eXtensible Markup Language), ele está gradualmente se tornando o principal meio de transmissão de dados. XML é uma linguagem autodescritiva e os próprios dados já contêm metadados, ou seja, informações sobre os próprios dados. Por exemplo: "Mencius Capítulo E 1757281793923net_lover1807581793923" Este conjunto de dados é difícil de ver o que significa literalmente e não está claro em quantos segmentos de dados ele consiste. pode ver claramente o significado de cada segmento de dados:
<Dados Pessoais>
<Pessoa>
<Nome>Mêncio Capítulo E</Nome>
<Altura>175</Altura>
<Peso>72</Peso>
<Tel>81793923</Tel>
</Pessoa>
<Pessoa>
<name>net_lover</name>
<Altura>180</Altura>
<Peso>75</Peso>
<Tel>81793923</Tel>
</Pessoa>
</PersonData>
A partir do XML acima, podemos não apenas ver claramente o que cada dado representa, mas também saber onde os dados estão divididos. Em nossas aplicações usuais, os resultados que obtemos podem estar na forma de arrays, coleções ou conjuntos de registros. Como os convertemos em dados autodescritivos no formato XML? Do ponto de vista do formulário de dados, XML é um formato de texto simples de strings puras. As strings são muito simples, rápidas e fáceis de transferir. As matrizes às vezes são muito lentas para transferir por referência e são muito problemáticas para processar e coletar. conjuntos são ambos objetos, o que causará uma diminuição no desempenho do computador durante o processamento, e esses objetos estão associados a uma plataforma específica, o que requer que a plataforma tenha um mecanismo de processamento integrado para lidar com as operações do objeto. XML já é um padrão W3C e é independente de plataforma. O único requisito para nossos computadores é ser capaz de processar strings XML simples, ou seja, um analisador XML. Ele pode analisar strings XML e decompor facilmente os dados em uma interface. segmentos de dados independentes para que possamos acessá-los. Os analisadores XML são pequenos, de alto desempenho e podem ser encontrados em todas as plataformas. Depois de recebermos os dados XML e analisá-los no estilo do exemplo acima, podemos convertê-los em diferentes representações por meio de XSLT (eXstensible Stylesheet Language Transformations). O uso do formato de dados XML para transmissão de dados tornará nosso trabalho de escrever o código do aplicativo mais simples e fácil, além de ter boa escalabilidade.
A seguir, vamos dar uma olhada em como converter nossos dados. Nosso exemplo foi escrito no Microsoft Windows 2000, IIS5, MSXML3 e ADO2.6. Os dados de amostra usam o banco de dados de exemplo Northwind que vem com o Microsoft SQL Server7.0. A razão pela qual usamos o SQL Server7 em vez do SQL Server2000 que suporta XML é considerar o princípio da universalidade. Nosso objetivo é processar os conjuntos de registros obtidos de diferentes tipos de fontes de dados, não apenas para suportar a saída XML como a fonte de dados do SQL Server2000. . Use ADO porque ele possui vários formatos e pode lidar com diferentes tipos de fontes de dados; use XML porque pode transmitir e analisar rapidamente. Mas o método de processamento neste exemplo também é adequado para qualquer ambiente com analisador XML da Microsoft, ADO2.5 ou versão superior do Windows, IIS, SQL Server.
Para simplificar, selecionamos apenas produtos cujo preço unitário seja menor ou igual a 20 dólares americanos, cujo estoque seja maior ou igual a 20 dólares americanos e cujo nome do produto seja menor ou igual a 6 caracteres:
<%
Dim objRecordset
Definir objRecordset = Server.CreateObject("ADODB.Recordset")
objRecordset.open _
"SELECIONE NomeDoProduto, PreçoUnitário, UnidadesEmEstoque" _
& "DE Produtos" _
& "ONDE PreçoUnitário <= 20" _
& "E UnidadesEm Estoque >= 20 " _
& "AND LEN(NomedoProduto) <= 6 " _
& "ORDEM POR NomeDoProduto", _
"Provedor=SQLOLEDB;"
& "Fonte de dados=AlgumSQLServer;"
& "Catálogo Inicial=Northwind;"
& "ID do usuário = MeuNomeUsuário;"
& "Senha=MinhaSenha;"
%>
Agora, usamos 3 métodos para converter o conjunto de registros obtido para o formato XML.
Primeiro, podemos percorrer todo o conjunto de registros, usar XML DOM (Document Object Model) e construir uma árvore de nós XML:
<%
Dim objXMLDOM, objRootNode, objNode
Definir objXMLDOM = Server.CreateObject("MSXML2.DOMDocument")
Definir objRootNode = objXMLDOM.createElement("xml")
objXMLDOM.documentElement = objRootNode
Faça enquanto NÃO objRecordset.EOF
Definir objRowNode = objXMLDOM.createElement("linha")
Definir objNode = objXMLDOM.createElement("ProductName")
objNode.text = objRecordset.Fields.Item("NomedoProduto").Valor
objRowNode.appendChild(objNode)
Definir objNode = objXMLDOM.createElement("UnitPrice")
objNode.text = objRecordset.Fields.Item("UnitPrice").Valor
objRowNode.appendChild(objNode)
Definir objNode = objXMLDOM.createElement("UnitsInStock")
objNode.text = objRecordset.Fields.Item("UnidadesEmEstoque").Valor
objRowNode.appendChild(objNode)
objRootNode.appendChild(objRowNode)
objRecordset.MoveNext
Laço
Definir objNode = Nada
Definir objRowNode = Nada
Definir objRootNode = Nada
Definir objRecordset = Nada
%>
Agora temos um objeto XML DOM. O desempenho desse método não é ideal quando o conjunto de registros é grande, porque o objeto do conjunto de registros ADO e o objeto XML DOM devem ser armazenados na memória do sistema ao mesmo tempo.
O segundo método é percorrer o conjunto de registros e gerar diretamente a própria string XML:
<%
DimstrXML
strXML = "<xml>"
objRecordset.MoveFirst
Faça enquanto NÃO objRecordset.EOF
strXML = strXML & "<linha>"
strXML = strXML & "<Nome do Produto>" _
& objRecordset.Fields.Item("NomedoProduto").Valor _
& "</ProductName>"
strXML = strXML & "<PreçoUnit>" _
& objRecordset.Fields.Item("PreçoUnitário").Valor _
& "</UnitPrice>"
strXML = strXML & "<UnidadesEmEstoque>" _
& objRecordset.Fields.Item("UnidadesEmEstoque").Valor _
& "</UnitsInStock>"
strXML = strXML & "</row>"
objRecordset.MoveNext
Laço
strXML = strXML & "</xml>"
Definir objRecordset = Nada
%>
No entanto, a maior falha dos dois métodos acima é que o código não pode ser reutilizado. Anotamos os nomes dos nós. Se consultarmos campos diferentes, também devemos alterar manualmente nosso código para atender às necessidades de diferentes nós. Nossa abordagem abaixo se tornará mais geral.
O terceiro método: método reutilizável.
<%
DimstrXML
strXML = "<xml>"
objRecordset.MoveFirst
Faça enquanto NÃO objRecordset.EOF
strXML = strXML & "<linha>"
Para cada varItem em objRecordset.Fields
strXML = strXML _
& "<" & varItem.name & ">" _
&varItem.value_
& "</" & varItem.name & ">"
Próximo
strXML = strXML & "</row>"
objRecordset.MoveNext
Laço
strXML = strXML & "</xml>"
Definir objRecordset = Nada
%>
Um método mais eficaz é usar diretamente o método save integrado do conjunto de registros, que pode converter automaticamente o conteúdo do conjunto de registros no formato XML. Depois de chamar o método save, podemos liberar imediatamente a instância do objeto recordset na memória. . O método save possui dois parâmetros: um é o local onde o XML será salvo e o outro é um indicador que indica o formato em que os dados serão salvos. Podemos salvar os dados como um objeto XML DOM (objeto ADO STREAM) ou salvá-los diretamente como um objeto ASP RESPONSE. Por uma questão de generalidade, salvamos-os como um XML DOM e usamos a constante adPersistXML ADO para o segundo parâmetro. . Veja como:
<%
Const adPersistXML = 1
Dim objXMLDOM
Definir objXMLDOM = Server.CreateObject("MSXML2.DOMDocument.3.0")
objRecordset.save objXMLDOM, adPersistXML
Definir objRecordset = Nada
%>
Este método é conveniente, rápido e livre de erros. Não há necessidade de alterar manualmente o nome do nó para consultas diferentes. No entanto, o XML produzido por este método não é suficientemente conciso. Dê uma olhada no resultado que ele produz:
<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
nome="linha"
content="eltOnly"
rs:CommandTimeout="30">
<s:AttributeType
nome="NomeDoProduto"
rs:número="1"
rs:writeunknown="true">
<s:datatype
dt:type="string"
dt:maxLength="40"
rs:maybenull="falso"/>
</s:AttributeType>
<s:AttributeType
nome = "Preço Unitário"
rs:número="2"
rs:nullable="verdadeiro"
rs:writeunknown="true">
<s:datatype
dt:type="número"
rs:dbtype="moeda"
dt:maxLength="8"
rs:precisão="19"
rs:fixedlength="true"/>
</s:AttributeType>
<s:AttributeType
name="UnidadesEmEstoque"
rs:número="3"
rs:nullable="verdadeiro"
rs:writeunknown="true">
<s:datatype
dt:type="i2"
dt:maxLength="2"
rs: precisão = "5"
rs:fixedlength="true"/>
</s:AttributeType>
<s:extends type="rs:rowbase"/>
</s:ElementType>
</s:Schema>
<rs:data>
<z:row
NomeDoProduto="Chai"
PreçoUnitário="18"
UnidadesInStock="39"/>
<z:row
NomeDoProduto="Konbu"
PreçoUnitário="6"
UnidadesInStock="24"/>
<z:row
NomeDoProduto="Tofu"
PreçoUnitário="23,25"
UnitsInStock="35"/>
</rs:data>
</xml>
O XML gerado automaticamente pelo ADO contém informações de esquema, que descrevem quais nós e atributos são permitidos neste XML e quais tipos de dados são usados, e os nós de dados são também aumentou o espaço para nome. As informações do esquema podem ser úteis quando a validação de dados é necessária ou para processamento mais complexo, mas, na maioria dos casos, usamos thin clients e não precisamos de informações do esquema. Podemos usar XSLT para separar as informações que desejamos e remover informações redundantes. Portanto, escrevemos o seguinte "DataCleaner.xsl":
<?xml versão="1.0"?>
<xsl:stylesheet versão="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:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:nome do elemento="xml">
<xsl:for-each select="/xml/rs:data/z:row">
<xsl:element name="linha">
<xsl:for-each select="@*">
<xsl:element name="{nome()}">
<xsl:valor-de select="."/>
</xsl:elemento>
</xsl:for-each>
</xsl:elemento>
</xsl:for-each>
</xsl:elemento>
</xsl:template>
</xsl:folha de estilo>
Este XSLT possui recursos reutilizáveis e é aplicável a diferentes resultados de consulta. A seguir está um exemplo de como usar este XSLT:
<%
Dim strCleanXML, objXMLDOM_XSLT
Definir objXMLDOM_XSLT = CreateObject("MSXML2.DOMDocument")
objXMLDOM_XSLT.load(Server.MapPath("DataCleaner.xsl"))
strCleanXML = objXMLDOM.transformNode(objXMLDOM_XSLT)
Definir objXMLDOM = Nada
Definir objXMLDOM_XSLT = Nada
%>
Após o processamento acima, strClaenXML é a string XML que desejamos.
<xml>
<linha>
<ProductName>Chai</ProductName>
<PreçoUnit>18</PreçoUnit>
<UnitsInStock>39</UnitsInStock>
</linha>
<linha>
<ProductName>Konbu</ProductName>
<PreçoUnit>6</PreçoUnit>
<UnitsInStock>24</UnitsInStock>
</linha>
</xml>
A string XML no formato acima é o estilo de conjunto de nós que vemos com frequência. Se você não deseja processar o campo em um nó, mas processá-lo em um nó de atributo, só precisamos fazer pequenas alterações no DataCleaber. xsl:
<?xml versão="1.0"?>
<xsl:stylesheet versão="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:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:nome do elemento="xml">
<xsl:for-each select="/xml/rs:data/z:row">
<xsl:element name="linha">
<xsl:for-each select="@*">
<xsl:attribute name="{nome()}">
<xsl:valor-de select="."/>
</xsl:atributo>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:elemento>
</xsl:template>
</xsl:folha de estilo>
A seguir está o resultado do uso do novo estilo, que é muito mais curto do que o uso de nós para representar o comprimento do campo. A velocidade de transferência será mais rápida:
<xml>
<row ProductName="Chai" UnitPrice="18" UnitsInStock="39"/>
<row ProductName="Konbu" UnitPrice="6" UnitsInStock="24"/>
</xml>
Até agora, apresentamos várias maneiras de obter dados em formato XML de conjuntos de registros ADO e também obtivemos a string mais simplificada. Mas há vários problemas aos quais você ainda precisa prestar atenção. Alguns valores de campo possuem caracteres que não são suportados em XML, como: "'< >&, como o nome da P&G Procter & Gamble, o nome da P&G Procter & Gamble. Produto Gumbo Mix do Chef Anton, etc. Você deve fazer isso ao converter. Executar o processamento de codificação. Há problemas a serem observados ao usar o método save no SDK do Microsoft ADO 2.6: 1. O método save funciona apenas em Recordset abertos. com campos dos tipos adVariant, adIDispatch e adIUnknown não são suportados savw 3. Há duas limitações ao salvar conjuntos de registros hierárquicos (formatos de dados): parametrizações e conjuntos de registros contendo atualizações não resolvidas.
Para melhorar ainda mais o desempenho, você pode colocar o trabalho de conversão em componentes COM/COM+, e o código ASP realiza apenas a apresentação final dos dados. Separe a camada de negócios, a camada de dados e a camada de apresentação. O ASP só precisa chamar o componente de dados. O componente de dados chama o procedimento armazenado do banco de dados, converte o resultado em XML e, finalmente, envia apenas a string XML simples de volta ao programa ASP. , e o ASP pode usar XSLT para converter o XML e enviar o resultado ao navegador.