|
|
|

|

|
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,
|
|
|
|

|