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 corretamentes (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.
Alexandre
Seria interessante para os iniantes se colocar o nome dos arquivos para cada estrutura de codigo.
Para fins didáticos e organizacional.
2001 - iMasters FFPA Informática Ltda - Todos os direitos reservados.