USUÁRIO:      SENHA:        SALVAR LOGIN ?    Adicione o VBWEB na sua lista de favoritos   Fale conosco 

 

  Dicas

  ASP - Active Server Page    (Miscelâneas)

Título da Dica:  Fórum em XML e ASP - Parte III / III
Postada em 3/10/2003 por ^HEAVY-METAL^            
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


Ufa acabamos hehe ,

Até a próxima,
 


CyberWEB Network Ltda.    © Copyright 2000-2024   -   Todos os direitos reservados.
Powered by HostingZone - A melhor hospedagem para seu site
Topo da página