Shopping Hospedagem Fórum Contato
     
   O portal do desenvolvedor ASP Florianópolis-SC, Domingo - 23 de Setembro de 2018  
Busca

Menu do site
Efetuar Login
Usuário:

Senha:

 Esqueceu a senha?
Login automático

 Cadastre-se
Fórum em XML e ASP
Avaliações: 9   -   Minha nota: Média Geral: 12  

Por Rubens Farias

Neste tutorial, iremos montar uma aplicação prática em XML, um fórum, usando como banco de dados o nosso querido XML. Para facilitar o aprendizado, dividimos este tutorial em 3 partes, da seguinte forma:

¤ Módulo 1: Modelagem de dados com DTD
¤ Módulo 2: Folhas de estilho XSL
¤ Módulo 3: Script ASP

Recomendo a leitura sequencial dos artigos. No entanto, você pode pular direto para a parte que te interessa ou descarregar os fontes no final do artigo. Também suponho familiaridade com o VBScript como linguagem de scripts para o ASP e a conhecimentos básicos de XML. No servidor, é necessário instalar o VBScript 5 ou superior além, é claro do MSXML3. Caso não os possua estes requisitos, leia nossos outros tutoriais.

Módulo 1 - Modelagem de dados com DTD

Antes de qualquer coisa, precisamos definir quais os campos queremos em nosso fórum. A estrutura que usaremos neste tutorial se baseará em dois nodes: o Groups, que conterá diversos elementos Group, armazenando o código do grupo, seu nome e uma descrição para o mesmo. Teremos também o node Messages, com elementos Message, com o código do grupo a que pertencem, o nome do usuário que postou a mensagem, seu email, endereço IP, data e hora da mensagem, o assunto da mesma e o corpo da mensagem.

Para definiremos esta estrutura e certificarmo-nos que os dados serão preenchidos corretamente (evitando erros de programação), usaremos o DTD abaixo.

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE ForumClass [

<!ELEMENT ForumClass ( Groups+, Messages* )>

<!ELEMENT Groups (Group+)>
   <!ELEMENT Group EMPTY>
   <!ATTLIST Group GroupId ID #REQUIRED
   Title       CDATA #REQUIRED
   Description CDATA #REQUIRED>

<!ELEMENT Messages   ( Message* )>
   <!ELEMENT Message ( Message* )>
   <!ATTLIST Message MsgId ID #REQUIRED
   GroupId   IDREF #REQUIRED
   UserName  CDATA #REQUIRED
   EMail     CDATA #REQUIRED
   IPAddress CDATA #REQUIRED
   TimeStamp CDATA #REQUIRED
   Subject   CDATA #REQUIRED
   Body      CDATA #REQUIRED>
]>

<ForumClass>
 <Groups>
  <Group GroupId="g1" Title="Fórum de testes" Description="Um fórum de uso genérico"/>
  <Messagens/>
 </Groups>
</ForumClass>


Um DTD (Document Type Definition) define a regras de utilização das tags XML, sendo usado inclusive para validar se um documento XML está formatado corretamente. Para maiores informações, veja nossa Introdução ao DTD.

Uma vez definido a estrutura dos dados, é necessário exibir os dados. Usaremos três arquivos XSL, responsável pela transformação do documento XML em HTML e um script ASP, que será responsável por coordenar as ações dos usuários, tais como responder mensagens, postar novas threads, etc., e por alterar o documento XML.

Módulo 2 - Folhas de estilo XSL

Comecemos pelos documentos XSL. Inicialmente, exibiremos os grupos disponíveis em um drop-down, que irá redirecionar a página para o grupo selecionado. Esta folha de estilo recebe como parâmetro opcional o grupo atual, para que o drop-down mantenha selecionado o grupo que o usuário se encontra.

<?xml version="1.0" encoding="iso-8859-1"?>
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" omit-xml-declaration="yes" />
 <xsl:variable name="GroupId"/>

 <xsl:template match="//Groups">
 <form action="" method="get" name="header">
  <div>
  Selecione o fórum:
   <select onchange="document.location.href = this.options[this.selectedIndex].value">
    <option value="index.asp">Página principal</option>
    <xsl:for-each select="Group">
     <xsl:element name="option">
      <xsl:if test="@GroupId = $GroupId">
       <xsl:attribute name="selected">selected</xsl:attribute>
      </xsl:if>
      <xsl:attribute name="value">index.asp?GroupId=<xsl:value-of select="@GroupId"/></xsl:attribute>
      ::<xsl:value-of select="@Title"/>
     </xsl:element>
    </xsl:for-each>
   </select>

   <xsl:if test="$GroupId != ''">

    <xsl:element name="a">
     <xsl:attribute name="href">index.asp?GroupId=<xsl:value-of select="$GroupId"/>&Message=-1</xsl:attribute>
     [ Nova mensagem ]
    </xsl:element>
    <xsl:element name="a">
     <xsl:attribute name="href">index.asp?GroupId=<xsl:value-of select="$GroupId"/></xsl:attribute>
     [ Principal ]
    </xsl:element>

   </xsl:if>

  </div>
 </form>
</xsl:template>
</xsl:stylesheet>


Para quem acha que passamos rápido demais:

¤ Definimos uma variável chamada GroupId, que utilizaremos posteriormente, para mantermos realçada a opção de grupo atual.
¤ No template que seleciona todos os elementos do node Groups, criamos os campos de um form, que servirá para redirecionar para o grupo desejado, alterando a opção do drop-down.
¤ Se o @GroupId (atributo do elemento Group) for igual a $GroupId (variável que definimos anteriormente), acrescente um "SELECTED", para manter o grupo atual como padrão no drop-down.
¤ Mostramos a descrição do grupo selecionado.
¤ Criamos os links para nova mensagem e para retornar a página que exibe todas as threads. Estudaremos em detalhes esses elementos posteriormente, no Módulo 3 deste tutorial.

Teremos também que exibir as threads. As mensagens serão mostradas hierarquicamente, mostrando as respostas das perguntas identadas, com a utilização recursiva do elemento <UL> do HTML. Queremos aqui exibir o assunto da mensagem, o autor, data e hora e número de respostas na thread.

<?xml version="1.0" encoding="iso-8859-1"?>
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" omit-xml-declaration="yes" />

<xsl:template match="Messages">
 <xsl:element name="ul">
  <xsl:apply-templates select="Message[@GroupId='x']"/>
 </xsl:element>
</xsl:template>

<xsl:template name="threads" match="Message">
 <li>
  <xsl:element name="a">
   <xsl:attribute name="href">index.asp?GroupId=<xsl:value-of select="@GroupId"/>&MsgId=<xsl:value-of select="@MsgId"/></xsl:attribute>
   <xsl:value-of select="@Subject"/>
  </xsl:element> -
  <b><xsl:value-of select="@UserName"/></b> -
  <i><xsl:value-of select="@TimeStamp"/></i>
  [<xsl:value-of select="count(.//Message)"/>]
  <ul>
   <xsl:apply-templates select="./Message"/>
  </ul>
 </li>
</xsl:template>
</xsl:stylesheet>


Aqui as coisas são mais simples, mas vamos passo-a-passo:

¤ No primeiro template, baseado no node Messages, criamos o elemento UL principal e aplicamos a segunda template apenas nos itens do grupo que estamos posicionados.
¤ Como você pode perceber, não usamos criamos uma variável GroupId neste template. No entanto, como os documentos XSL são também documentos XML, poderemos alterar o valor do node posteriomente.
¤ No template threads, exibimos os dados de identificação da mensagem (autor, data, etc.) e o link para exibirmos a mensagem.
¤ Um detalhe diferente é a contagem de nodes filhos do node atual. Isso é feito com a função count(.//Message). Traduzindo: do local atual (.) pegue todas os elementos Message, independentemente de o quão aninhados eles estão (//Message).
¤ Criamos um novo elemento <UL> e aplicamos os templates relacionados novamente. Então, recursivamente, os dados vão sendo montados.

Se você está acompanhando o raciocício até agora, ótimo! Só falta montar a rotina para a exibição de mensagens. Ela é um pouco maior que as demais, mas também usa conceitos simples. Vamos comentar cada parte separadamente e em detalhes:

<?xml version="1.0" encoding="iso-8859-1" ?>
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" omit-xml-declaration="yes" />

 <xsl:variable name="UserName"/>
 <xsl:variable name="EMail"/>
 <xsl:variable name="GroupId"/>
 <xsl:variable name="NewMessage">0</xsl:variable>


Cabeçalho padrão, identificando o documento e o namespace usado. Também declaramos algumas variáveis que usaremos posteriormente.

<xsl:template match="Message">
 <form action="index.asp?GroupId=@GroupId" method="POST">
  <table border="0" style="border: 1 solid black;" align="center" width="75%">
  <xsl:if test="$NewMessage = 0">
   <tr class="color1">
    <td>Assunto:</td>
    <td><xsl:value-of select="@Subject"/></td>
   </tr>
   <tr class="color2">
    <td>Data:</td>
    <td><xsl:value-of select="@TimeStamp"/><small> (<xsl:value-of select="@IPAddress"/>)</small></td>
   </tr>
   <tr class="color2">
    <td>De:</td>
    <td>
     <xsl:element name="a">
      <xsl:attribute name="href">mailto:<xsl:value-of select="@EMail"/></xsl:attribute>
       <xsl:attribute name="target">_blank</xsl:attribute>
      <xsl:value-of select="@UserName"/>
     </xsl:element>
     <<xsl:value-of select="@EMail"/>>
    </td>
   </tr>
   <tr class="color3">
    <td valign="top">Mensagem:</td>
    <td style="text-align: justify;">
     <xsl:call-template name="replace">
      <xsl:with-param name="content" ><xsl:value-of select="@Body"/></xsl:with-param>
      <xsl:with-param name="character"> </xsl:with-param>
      <xsl:with-param name="replace" />
     </xsl:call-template>
    </td>
   </tr>
  </xsl:if>
  <xsl:call-template name="NewMessage" />
 </table>
 </form>
</xsl:template>

<xsl:template name="replace" >
 <xsl:param name="content" />
 <xsl:param name="character"/>
 <xsl:param name="replace" />

 <xsl:if test="not (contains( $content, $character ))">
  <xsl:value-of select="$content"/>
 </xsl:if>

 <xsl:if test="contains( $content, $character )">
  <xsl:value-of select="substring-before($content,$character)"/><br />
  <xsl:value-of select="$replace"/>

  <xsl:if test="contains( substring-after($content,$character), $character )">
   <xsl:call-template name="replace">
    <xsl:with-param name="content" ><xsl:value-of select="substring-after($content,$character)"/></xsl:with-param>
    <xsl:with-param name="character"><xsl:value-of select="$character"/></xsl:with-param>
    <xsl:with-param name="replace" ><xsl:value-of select="$replace"/></xsl:with-param>
   </xsl:call-template>
  </xsl:if>
  <xsl:if test="not ( contains( substring-after($content,$character), $character ) )">
   <xsl:value-of select="substring-after($content,$character)"/>
  </xsl:if>
 </xsl:if>
</xsl:template>


Este template é o responsável pela exibição da mensagem. Detalhadamente:

Caso a variável NewMessage seja diferente de zero, significa que estamos editando uma nova mensagem, nao subordinada a nenhuma outra (uma nova thread). Então não é exibida a mensagem original, pois nao há nenhuma :-)
Criamos então a estrutura da tabela onde a mensagem estará contida, exibindo os dados do remente da thread anterior.
A única coisa diferente neste template é a rotina de quebra de linhas, exibida em negrito, necessária para a exbição correta da mensagem. Como a mensagem vai ser montada em um <TEXTAREA>, quebras de linhas podem ocorrer e devem ser exibidas como sendo <BR>. Para tanto a segunda template foi contruída. Ela faz uso de funções de manipulação de strings. Para estudar essas funções, baixe o XML SDK.

<xsl:template name="NewMessage">
 <tr class="color1">
  <td colspan="2">
   <xsl:if test="$NewMessage = 0">Resposta:</xsl:if>
   <xsl:if test="$NewMessage = 1">Nova mensagem:</xsl:if>
   <a name="new" />
  </td>
 </tr>
 <tr class="color2">
  <td>Usuário:</td>
  <td>
    <xsl:element name="input">
    <xsl:attribute name="type">text</xsl:attribute>
    <xsl:attribute name="name">UserName</xsl:attribute>
    <xsl:attribute name="size">30</xsl:attribute>
    <xsl:attribute name="value"><xsl:value-of select="$UserName"/></xsl:attribute>
   </xsl:element>
  </td>
 </tr>
 <tr class="color2">
  <td>Email:</td>
   <td>
    <xsl:element name="input">
    <xsl:attribute name="type">text</xsl:attribute>
    <xsl:attribute name="name">EMail</xsl:attribute>
    <xsl:attribute name="size">30</xsl:attribute>
    <xsl:attribute name="value"><xsl:value-of select="$EMail"/></xsl:attribute>
   </xsl:element>
  </td>
 </tr>
 <tr class="color2">
  <td>Assunto:</td>
  <td>
   <xsl:element name="input">
    <xsl:attribute name="type">text</xsl:attribute>
    <xsl:attribute name="name">Subject</xsl:attribute>
    <xsl:attribute name="size">30</xsl:attribute>
    <xsl:attribute name="value">
     <xsl:if test="$NewMessage = 0">Re: <xsl:value-of select="@Subject"/></xsl:if>
     <xsl:if test="$NewMessage = 1"/>
    </xsl:attribute>
   </xsl:element>
  </td>
 </tr>
 <tr class="color3">
  <td valign="top">Mensagem:</td>
   <td><textarea cols="70" rows="10" name="Body"></textarea></td>
 </tr>
 <tr class="color3">
  <td colspan="2" align="center">
   <xsl:element name="input">
    <xsl:attribute name="type">hidden</xsl:attribute>
    <xsl:attribute name="name">Id</xsl:attribute>
    <xsl:attribute name="value">
     <xsl:if test="$NewMessage = 0"><xsl:value-of select="@MsgId"/></xsl:if>
     <xsl:if test="$NewMessage = 1">-1</xsl:if>
    </xsl:attribute>
    </xsl:element>
   <xsl:element name="input">
    <xsl:attribute name="type">hidden</xsl:attribute>
    <xsl:attribute name="name">GroupId</xsl:attribute>
    <xsl:attribute name="value"><xsl:value-of select="$GroupId"/></xsl:attribute>
    </xsl:element>
   <input type="hidden" name="action" value="new" />
    <xsl:element name="input">
    <xsl:attribute name="type">submit</xsl:attribute>
    <xsl:attribute name="value">
     <xsl:if test="$NewMessage = 0">Postar resposta</xsl:if>
     <xsl:if test="$NewMessage = 1">Postar nova mensagem:</xsl:if>
    </xsl:attribute>
   </xsl:element>
  </td>
 </tr>
</xsl:template>
</xsl:stylesheet>


Esse foi um pouco maior que os demais, mas nao envolve nada descomunal. é apenas o trabalho de criar os elementos necessários do form, para enviar a mensagem. Mas, analisando um pouco mais profundamente, podemos ressaltar alguns pontos a comentar:

Nome e usuário são armazenados em variáveis session no script ASP, poupando o usuário de digitá-los em cada nova mensagem.
O primeito trecho destacado em negrito aponta um recurso novo: a definição dos atributos de elementos <INPUT>, baseado no que estams fazendo. Caso a variável NewMessage esteja com o valor 0, estamos respondendo a uma mensagem, então os dados relacionados a ela são exibidos. Do contrário, é mostrado em branco, conforme já haviamos comentado anteriormente.
No segundo trecho em negrito, enviamos o id da mensagem a ser respondida (para criarmos a thread) ou -1, indicando que é uma nova mensagem. Esse recurso também éé usado para indicarmos para o usuário o que ele está fazendo: postando uma nova mensagem ou respondendo a uma já postada.

Na próxima parte, utilizaremos os conceitos estabelecidos aqui, para construirmos o script ASP que será encarregado de construir o fórum e torná-lo operacional.

Módulo 3 - Script ASP

Chegando aqui, alguns critérios já estão definidos:

¤ Sempre passaremos o grupo atual pela URL, na variável GroupId.
¤ Se o script ASP receber Message = -1, significa que queremos incluir uma nova mensagem; valores diferentes deste indicam que uma mensagem está sendo respondida.

Como feito anteriormente, comentaremos cada parte do script, explicitando as operações envolvidas.

<%
Option Explicit
 Dim xmlDoc, xmlStyle, GroupStyle, MsgStyle, WorkNode, dbPath, Action
 Dim id, username, email, IPAddress, body, subject, timestamp
 Dim n, GroupId, Fields, newNode, newElement, InsertPoint
 Dim StartTimer, MessageId, AllRight

  StartTimer = timer()
  Response.Buffer = TRUE
  Response.Expires = 0
  Session.LCID = 1046
  dbPath = server.MapPath( "db/" )
  Action = request.form( "action" )
  AllRight = false
  set xmlDoc = LoadXMLData( dbPath & "/forum.xml" )
  set xmlStyle = LoadXMLData( dbPath & "/forum.xsl" )
  set GroupStyle = LoadXMLData( dbPath & "/groups.xsl" )
  set MsgStyle = LoadXMLData( dbPath & "/message.xsl" )


Apenas definimos as variáveis usadas pela aplicação, o diretório onde ficarão os arquivos (no diretório db, dentro do diretório com o index.asp) e carregamos os arquivos da aplicação (a função LoadXMLData é explicada mais à frente).

if Action = "new" then
   Id = request.form( "id" )
   UserName = request.form( "username" )
   EMail = request.form( "email" )
   Subject = request.form( "subject" )
   Body = request.form( "Body" )
   GroupId = request.form( "GroupId" )
   IPAddress = request.serverVariables( "REMOTE_ADDR" )
   TimeStamp = date() & " " & time()

   if isEmail( EMail ) and len( UserName ) > 0 and len( Body ) > 0 then

      Session( "UserName" ) = UserName
      Session( "EMail" ) = EMail


       set newNode = xmlDoc.createElement( "Message" )
       newNode.setAttribute "GroupId", GroupId

       newNode.setAttribute "MsgId" , "m" & ( xmlDoc.getElementsByTagName("Message").length + 1 )
       Fields = array( "UserName", "EMail", "IPAddress", "TimeStamp", "Subject", "Body" )
       for n = 0 to uBound( Fields ) : newNode.setAttribute Fields( n ), eval( fields( n ) ) : next

      set InsertPoint = xmlDoc.selectSingleNode( "//Message[@MsgId=" & Format( id ) & _
      " and @GroupId = " & Format( GroupId ) & "]" )
      if ( InsertPoint is nothing ) then set InsertPoint = xmlDoc.selectSingleNode( "//Messages" )
      InsertPoint.appendChild newNode
      AllRight = true

   else

      response.write "<center><u>E-mail inválidos ou campo necessário em branco</u></center>"
      response.end

   end if

end if

' Gravar todas as alterações, se necessário e estiver tudo ok
  if AllRight then xmlDoc.save( dbPath & "/forum.xml" )

%>


Nesta parte montamos a inclusão de novas mensagens. Funciona basicamente da seguinte forma:

¤ Verificamos se a variável Action indica trata-se de uma nova mensagem.
¤ Lemos os campos que devem ter sido enviados pelo form que criamos no message.xsl
¤ Caso algum dos campos não esteja preenchido corretamente, exibimos uma mensagem de alerta.
¤ Colocamos o nome do usuário e seu email em uma variável session, para poupar digitação.
¤ Criamos um novo elemento Message e definimos suas propriedades, na área em negrito. Ao invés de entrar uma a uma, optamos por colocar todas em uma matriz, o que facilita posteriores manutenções. Outro detalhe importante é o valor do atributo MsgId, que é definido como sendo o número de mensagens do fórum. Isso é uma forma de criar valores únicos para a chave de pesquisa de mensagens. Note que colocamos um 'm' no início da chave, pois no DTD definimos esta propriedade como ID, que obriga que seu conteúdo inicie com um caracter.
¤ O próximo passo é definir o ponto de inserção deste node. Pesquisamos o id passado para o script, juntamente com o grupo a que essa mensagem se refere. Caso não seja encontrado, assumimos que é uma mensagem nova e inserimos dentro do node Messages.
¤ Adicionamos o elemento criado no node selecionado no passo anterior.
¤ Salvamos o documento XML, se estiver vindo de uma inclusão de mensagem.

 <html>
 <head>
 <title>Fórum XML by www.xmlware.com.br</title>
 <style type="text/css">
 <!--
 * { font-family: Arial; }
 A:hover { text-decoration: underline; color: gray; }
 .Color1 { background-color: gray; color: white; }
 .Color2 { background-color: silver; }
 .Color3 { background-color: #DDDDDD; }
 // -->
 </style>
 </head>
 <body>


Apenas o cabeçalho do documento HTML, definindo a folha de estilos CSS usada.

Uma parte um pouco mais complexa, que é a alteração do documento XSL vem agora. Mas veremos quer não é nada complicado, quando entendemos o que estamos fazendo. Tente ler cada linha de código com calma e nao passe para a seguinte, se nao souber o que está acontecendo.

<%

set WorkNode = GroupStyle.selectSingleNode( "//xsl:variable[@name=""GroupId""]" )
WorkNode.text = GroupId

set WorkNode = xmlDoc.selectSingleNode( "//Groups" )
response.write WorkNode.transformNode ( GroupStyle )



Aqui fazemos a passagem de um parâmetro para o groups.xsl, que informa qual o grupo que está sendo visualizado neste momento. Como vimos anteriormente, isso servirá para mantermos selecionado o grupo atual no drop-down. Para exibi-lo, selecionamos apenas o node //Groups e fazemos sua transformação com o XSL.

if GroupId <> "" then

   set WorkNode = xmlStyle.selectSingleNode("//xsl:apply-templates[@select=""Message[@GroupId='x']""]")
   if not ( WorkNode is Nothing ) then
      if len( MessageId ) = 0 then
         WorkNode.setAttribute("select") = "Message[@GroupId=" & Format( GroupId ) & "]"
      else
         WorkNode.setAttribute("select") = "//Message[@GroupId=" & Format( GroupId ) & _
         " and @MsgId=" & Format( MessageId ) & "]/Message"
      end if
   end if
   response.write xmlDoc.transformNode( xmlStyle )


Caso já haja um grupo selecionado, vamos mostrar as mensagens daquele grupo. Começamos por pesquisar um node xsl:apply-templates que possua na atributo select a string Message[@GroupId='x'].

Como comentamos anteriormente, poderíamos definir uma variável que substituiria o 'x', mas fizemos desta forma para reforçar a idéia que documentos XSL também são documentos XML, além de praticar um pouco o XPath. Caso tenhamos encontrado o node em questão (sempre será verdadeiro, a menos que ocorra um erro de digitação no forum.xsl), verificamos se estamos procurando por uma mensagem em particular ( len( MessageId ) <> 0 ). Se sim, alteramos a condição do atributo select para mostrar apenas a thread desejada ou, caso contrário todas as mensagens.

Definimos anteriomente que, caso o MessageId fosse igual a -1, estariamos editando uma nova mensagem. Neste trecho do código,

   if isNumeric( MessageId ) then 'Nova mensagem

     set WorkNode = xmlDoc.selectSingleNode( "//Message[@GroupId=" & Format( GroupId ) & "]" )

      'Se nao existe nenhuma mensagem no grupo, usar um node vazio para exibir a nova mensagem
      if WorkNode is Nothing then
        set WorkNode = xmlDoc.createElement( "Message" )
        WorkNode.appendChild xmlDoc.createElement( "Message" )
      end if

   else

      set WorkNode = xmlDoc.selectSingleNode( "//Message[@GroupId=" & Format( GroupId ) & _
      " and @MsgId=" & Format( MessageId ) & "]" )

   end if


Definimos anteriomente que, caso o MessageId fosse igual a -1, estariamos editando uma nova mensagem. Neste trecho do código, selecionamos a thread em questão para ser exibida. O que fazemos de novo aqui é criar um node em branco, caso seja a primeira mensagem do grupo, evitando problemas na exibição no código HTML gerados pela message.xsl.

   if not ( WorkNode is Nothing ) then

      MsgStyle.selectSingleNode("//xsl:variable[@name=""UserName""]" ).text = Session( "UserName" )
      MsgStyle.selectSingleNode("//xsl:variable[@name=""EMail""]" ).text = Session( "EMail" )
      MsgStyle.selectSingleNode("//xsl:variable[@name=""GroupId""]" ).text = GroupId
      MsgStyle.selectSingleNode("//xsl:variable[@name=""NewMessage""]" ).text = iif( isNumeric( MessageId ), 1, 0 )
      response.write WorkNode.transformNode( MsgStyle )

   end if

else

    response.write xmlDoc.transformNode( xmlStyle )

end if

response.write "<center><font size=""-2"">Página gerada em " & round( timer() - StartTimer, 2 ) & " segundos<br>" & _
              "Baseado no tutorial oferecido pelo site <a href=""www.xmlware.com.br"">X M L W A R E</a></font></center>"


Aqui, apenas terminamos o processo de exibição do form que irá permitir o envio de novas mensagens ao fórum. Passamos para o message.xsl as variáveis UserName, EMail, GroupId e NewMessage, para que ele saiba o que fazer, mediante alteração do XSL.

Com isso, a aplicação já está funcional. Vamos terminar analisando algumas funções acessórias:

function LoadXMLData( path )
   dim Object
   set Object = Server.CreateObject("MSXML2.DOMDocument")
   Object.async = false
   Object.preserveWhiteSpace = true
   Object.load ( path )
   if Object.parseError <> 0 then
     response.write Object.parseError.srcText & "<br>" & _
     Object.parseError.reason & " Linha " & _
     Object.parseError.line & " Col " & Object.parseError.linepos
     response.end
   end if
   set LoadXMLData = Object
end function


A função LoadXMLData é a reponsável por criar o objeto MSXML2.DOMDocument e carregar o arquivo XML, seja ele dados (.XML) ou folhas de estilo (.XSL). Caso haja algum problema na carga (documento digitado incorretamente, dados que violem o DTD, etc.), o processamento é interrompido, exibindo a causa do problema.

function isEmail(byval sMailAddress)
   dim re
   set re = new RegExp
   re.Global = false
   re.IgnoreCase = true
   re.Pattern = "^(\w|[^_]\.[^_]|[\-])+(([^_])(\@){1}([^_]))(([a-z]|[\d]|[_]|[\-])+|([^_]\.[^_])*)+\.[a-z]{2,3}$"
   isEmail = re.test(sMailAddress)
   set re = nothing
end function


A função isEmail é mais engenhosa e foi retirada do site www.aspemporium.com. O objetivo é forçar a entrada de um endereço de email válido, mediante uso de uma regular expression, muito usada por programadores Perl. Note que, para utilizá-la, o VBScript versão 5 ou superior deve estar instalado no server. Atualizações estão disponíveis em http://msdn.microsoft.com/scripting/.

function iif( condicao, valor1, valor2 )
   if condicao then iif = valor1 else iif = valor2
end function
function format( texto )
   format = chr( 39 ) & texto & chr(39)
end function

%>


Essas duas são apenas "cosméticas". A primeira é uma que faz falta no VBScript: uma função condicional. Sem ela, teríamos que utilizar a instrução IF sempre que quiséssemos avaliar uma condição e seu uso permite esse recurso "inline". A segunda apenas formata uma string, acrescentado aspas antes e depois do texto.

 </body>
</html>


Apenas fechamos os elementos do HTML (um hábito que deve ser cultivado, principalmente com a aprovação do XHTML pelo W3C, que deve tornar-se um padrão amplamente utilizado em breve).

Acredite ou não já está tudo feito. Definimos a estrutuda dos dados com o DTD, criamos os arquivos .XSL que vão transformar o documento XML em HTML e construímos o back-end da aplicação.

Todos os direitos autorais dos artigos pertencem ao seu autor






SuperASP do Brasil Ltda

03.066.522/0001-84
Av. Rio Branco 433 - Centro - Florianopolis - SC
Contato

© 2001/2008 - Superasp do Brasil Ltda. Todos os direitos reservados