

| com exemplos em VB |
| Componente para deixar forms em Vb semelhantes às telas do winnamp |
| Componente para colocar sua aplicação VB no Systray |
| Componente para transformar sua aplicação VB em serviço |
| Ferramentas úteis para quem usa Olap Server |
| |

![]() |
||||||||
|
|
||||||||
Quer
saber mais?
Certifique-se como MCP em SQL Server
Faça um treinamento na Búfalo Informática
Trocando
dados em XML com SQL Server Parte 3 : Templates
Utilizando Templates de querys para aumentar a segurança
| Após este arquivo você gostará de estudar : |
Apenas relembrando : Nos artigos anteriores vimos como utilizar o "Configure SQL XML Support in IIS" para configurarmos um diretório virtual para o SQL Server. Vimos como fazer querys via URL e querys via XPATH, utilizando diretamente o browser, páginas ASP ou aplicações VB.
Mas em todos os casos que vimos detalhes da query eram transmitidos via URL, o que não é de todo seguro.
Para resolvermos esse problema podemos criar templates já contendo as querys pré-definidas e armazenarmos estes templates no servidor. Desta forma as aplicações poderão apenas consultar os templates e obter o resultado oferecido por eles.
Existem 2 tipos de templates : Templates de querys via XPATH e templates de query usando SQL. Vamos analisar os 2.
Formato padrão dos templates
O formato geral de um template é o seguinte :
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql"
sql:xsl='XSL FileName' >
<sql:header>
<sql:param>..</sql:param>
<sql:param>..</sql:param>...n
</sql:header>
<sql:query>
sql statement(s)
</sql:query>
<sql:xpath-query mapping-schema="SchemaFileName.xml">
XPath query
</sql:xpath-query>
</ROOT>
|
Tudo neste template é opcional. As instruções utilizadas no template, porém, pertencem ao namespace sql definido junto ao Root, portanto essa definição é obrigatória. Mas "sql" é apenas um alias, pode ser substituído por qualquer coisa.
Vejamos cada elemento do template :
ROOT
É a raiz do documento XML, todo documento XML é obrigado a ter um ROOT. Para o efeito de montagem de um template o ROOT pode possuir qualquer nome.
SQL:HEADER
É utilizada para agrupar as definições de parâmetros para as querys, SQL:PARAM
SQL:PARAM
Cada um desses elementos é a definição de um parâmetro para a query contida no template.
SQL:QUERY
Especifica uma query SQL.
SQL:XPATH-QUERY
Especifica uma query em XPATH. As querys em XPATH são executadas sobre um schema que tenha sido previamente definido, por isso é obrigatória a especificação do schema junto a este elemento. A utilização do schema funciona de forma semelhante ao que fizemos no artigo anterior, conforme veremos exemplos a seguir.
SQL:XSL
Esse atributo é utilizado para especificar a style-sheet que será utilizada para formatar o resultado da query
Mapping-Schema
Este atributo é utilizado para apontarmos para o arquivo de schema utilizado para executar a xpath-query.
Para que as querys via template funcionem adequadamente é necessário termos um virtual name configurado como sendo do tipo template. A permissão de execução de querys via template também deve estar configurada, porém as demais permissões não precisam estar.
Essa configuração de permissões garante que apenas as querys já contidas em templates poderão ser executadas, não sendo possível a um invasor transmitir para o servidor a query que deseja executar.
Para que os templates possam ser executados precisam ser armazenados no caminho físico que é apontado pelo virtual name do tipo templates ou em um de seus sub-diretórios.
Nos artigos anteriores já utilizávamos um virtual directory chamado SQL, apontando para o banco pubs. Vamos supor que criamos um virtual name chamado "teste".
Templates de querys XPATH
Os templates de query via XPATH nos permitem armazenarmos em arquivo as querys via XPATH que havíamos analisado no artigo anterior. Isso evita que qualquer query via XPATH possa ser executada, desta forma serão permitidas apenas querys pré-armazenadas na forma de templates.
As querys via XPATH precisam de um Schema para serem executadas. Os Schemas definem um formato de XML com base no banco de dados. A query é processada sobre o XML definido pelo Schema e não sobre o banco de dados diretamente.
Podemos então utilizar um dos schemas que já utilizamos no artigo anterior, veja :
<?xml version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
xmlns:dt="urn:schemas-microsoft-com:datatypes"
xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<ElementType name="Employee" sql:relation="Employee" >
<AttributeType name="Emp_Id" />
<AttributeType name="fname" />
<AttributeType name="lname" /> <attribute type="Emp_Id" />
<attribute type="fname" />
<attribute type="lname" /> </ElementType>
<ElementType name="Publisher" sql:relation="Publishers" >
<AttributeType name="pub_id" />
<AttributeType name="pub_name" />
<AttributeType name="city" />
<AttributeType name="country" /> <attribute type="pub_id" />
<attribute type="pub_name" />
<attribute type="city" />
<attribute type="country" />
<element type="Employee" >
<sql:relationship
key-relation="Publishers"
key="pub_id"
foreign-key="pub_id"
foreign-relation="Employee" />
</element>
</ElementType>
</Schema>
|
Este schema relaciona as tabelas publishers e employees. As querys via XPATH que realizaremos serão feitas sobre este schema.
Além do schema podemos também utilizar um arquivo xsl para formatar o resultado da query. Veja Quando utilizar e quando não utilizar um xsl em um template :
Eis um exemplo de XSL para este nosso template que estamos construindo :
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match = "/">
<HTML>
<head>
<style>
.pub {background-color:lightblue}
.emp {background-color:lightgreen}
</style>
</head>
<BODY>
<table width="100%" border="0" cellspacing="0" cellpading="0">
<xsl:apply-templates select="//Publisher" />
</table>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="//Publisher">
<tr class="pub">
<xsl:apply-templates select="./@*" />
</tr>
<xsl:apply-templates select="./Employee" />
</xsl:template>
<xsl:template match="//Employee">
<tr class="emp">
<xsl:apply-templates select="./@*" />
</tr>
</xsl:template>
<xsl:template match="//@*">
<td>
<xsl:value-of select="." />
</td>
</xsl:template> </xsl:stylesheet> |
Veja como fica a chamada do template via URL :
http://localhost/sql/teste/querypubs.xml
Observe a formação desta URL :
Servidor/diretório virtual do SQL/Virtual name do tipo template/tempate

Figura 1 : Quando o XSL é especificado dentro do template,
o retorno default é em xml, nos obrigando a utilizar o parâmetro
contentType na url
Como você poderá observar ao testar esse exemplo, o template por default gera um retorno em XML. Mesmo tendo aplicado o XSL diretamente no template, o HTML retornado será interpretado e exibido pelo browser como se fosse XML.
Para corrigir isso devemos alterar o contentType do resultado para text/xml utilizando para isso um parâmetro chamado contentType. Veja o exemplo :
http://localhost/sql/teste/querypubs.xml?contenttype=text/html
Se o XSL não estivesse já especificado no template poderíamos ainda especifica-lo, veja :
http://localhost/sql/teste/querypubs.xml?xsl=publishers.xsl
Observe que quando o XSL encontra-se especificado dentro do template somos obrigados a especificar o contentType, porém quando o XSL é passado como parâmetro o contentType é identificado automaticamente.

Figura 2 : Tela de chamada do template com o XSL sendo aplicado
na URL
Neste exemplo que fizemos a query xpath encontra-se fixa, dará sempre o mesmo resultado. Porém os templates nos permitem fazer a especificação de parâmetros para as querys. Para isso devemos utilizar os elementos sql:header e sql:param.
Veja um exemplo de um template preparado para receber parâmetros :
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<sql:header>
<sql:param name='PubId'>0877</sql:param>
</sql:header>
<sql:xpath-query mapping-schema="pubs.xml">
/Publisher[@pub_id=$PubId]
</sql:xpath-query>
</ROOT>
|
Observe que dentro da tag sql:param existe a especificação de um PubId. Esse é o valor default que será utilizado pelo template caso o parâmetro não seja transmitido.
Veja um exemplo da chamada deste template :
http://localhost/sql/teste/querypubs.xml?PubId=0877&xsl=publishers.xsl
Estamos nesta url não apenas transmitindo o parâmetro esperado pelo template, mas também o xsl. Claro que tudo isso é opcional, até mesmo o parâmetro do template, pois não sendo passado será assumido o valor default especificado no template.
Criando aplicações para acessar os dados
Podemos utilizar este template em nossas aplicações. Por exemplo, é muito simples fazer um formulário html que utilize este template para fazer uma query no banco de dados, veja :
<html>
<body>
<form method=get action=http://localhost/sql/teste/querypubs.xml>
PubId : <input type=text name=PubId>
<input type=hidden name=xsl value="publishers.xsl">
<input type=submit value="Pesquisar">
</form>
</body>
</html>
|
Deve-se porém ter muita atenção aos detalhes : O parâmetro PubId é sensível a caixa da letra.
Observe que neste exemplo estamos passando o parâmetro XSL e contentType, pois desejamos que o XSL seja aplicado para que o usuário já veja o resultado final assim que clicar no pesquisar.
Se a nossa aplicação desejasse, porém, realizar algum processamento com as informações retornadas, poderíamos não transmitir esses dois parâmetros, receber as informações de volta em XML.
Podemos fazer um exemplo de processamento do XML em uma aplicação VB. Veja a imagem do formulário da aplicação e observe abaixo como fica o código do botão Pesquisar (não esqueça que é necessário fazer o references para o Microsoft XML 3.0) :
Private Sub cmdPesquisar_Click()
Dim doc As New DOMDocument
Dim pub As IXMLDOMElement
Dim item As IXMLDOMElement List1.Clear doc.async = False
doc.Load "http://localhost/sql/teste/querypubs.xml?PubId=" & Text1.Text 'MsgBox doc.xml Set pub = doc.documentElement.childNodes(0) For Each item In pub.childNodes
List1.AddItem item.getAttribute("fname") & " " & item.getAttribute("lname")
Next
End Sub
|

Figura 3 : Aplicação VB acessando o template
Templates para querys SQL
Até agora vimos o template sendo montado com uma query em XPATH. Mas podemos também fazer um template com query em SQL ao invés de XPATH. Neste caso não precisaremos do Schema, pois através do SQL já recuperaremos os dados da forma que desejarmos.
Porém na query usando SQL deveremos já trazer os dados em formato XML. Para isso teremos que usar a clausula for xml auto existente no SQL Server 2000.
Veja como fica o template :
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<sql:header>
<sql:param name='PubId'>0877</sql:param>
</sql:header>
<sql:query>
select Publisher.pub_id,pub_name,city,country,
emp_id,fname,lname,job_id from publishers Publisher,Employee
where Publisher.pub_id=Employee.pub_id and Publisher.pub_id=@pubid for xml auto
</sql:query>
</ROOT>
|
A query SQL está fazendo o relacionamento entre Publishers e Employee, sendo que o for xml auto se encarregará de, com base neste relacionamento, montar a relação entre os elementos do XML. Com isso este template está gerando o mesmo resultado que o anterior, mas nesse caso não é necessário arquivo de Schema para o funcionamento do template.
Observe que o símbolo para indicar o parâmetro na query SQL muda : No xpath era $, no SQL utilizamos a @
A chamada do template ocorre de forma idêntica ao anterior, veja :
http://localhost/sql/teste/querypubsSQL.xml?xsl=publishers.xsl&PubId=0736
Tanto na aplicação ASP como na aplicação Vb basta alterar o nome do arquivo para que a aplicação passe a funcionar com o novo template. Isso porque neste exemplo tomei o cuidado de manter nos dois templates a mesma estrutura de XML.
Dennes Torres
© Búfalo Informática,
Treinamento e Consultoria -
Rua Álvaro Alvim, 37 Sala 920 - Cinelândia - Rio de Janeiro / RJ
Tel.: (21)2262-1368 (21) 9240-5134 (21) 9240-7281 e-Mail: contato@bufaloinfo.com.br