
O
Projeto Kepler oferece um módulo de interface com
Expat, um processador XML. O módulo se chama
LuaExpat.
Na verdade o módulo oferece diretamente apenas uma função:
lxp.new(), que retorna um objeto processador de XML (
parser). Esta função recebe como parâmetro uma tabela especial de
callbacks, que são as funções responsáveis por tratar os elementos XML.
Se for passado como parâmetro uma tabela vazia, o
parser apenas verificará a integridade do código XML.
Portanto, para usar LuaExpat para tratar XML, é preciso conhecer duas coisas: os
callbacks e o
parser.
Callbacks
Na tabela de
callbacks, as chaves devem possuir nomes específicos que indicam em que caso cada
callback será usado. Os valores são funções: os
callbacks.
Há toda uma lista de
callbacks (neste momento em que escrevo há quinze
callbacks). Vamos dar uma olhadinha apenas em três principais:
StartElement,
EndElement e
CharacterData.
StartElement é chamado quando é encontrada a abertura de um elemento (
tag), por exemplo
<xhtml:div id="main">. A função possui três argumentos:
parser,
elementName (nome do elemento) e
attributes (atributos).
O primeiro argumento recebe o próprio
parser.
O segundo,
elementName, recebe o nome do elemento (no exemplo,
xhtml:div).
O terceiro,
attributes, recebe uma tabela com os atributos, tanto de forma indexada quanto associativa. Assim, no exemplo (
<xhtml:div id="main">):
{
[1] = "main";
id = "main"
}
EndElement é chamado quando é encontrado o fechamento de um elemento, por exemplo
</xhtml:div>. A função possui dois argumentos:
parser e
elementName (nome do elemento).
Quando é encontrado um elemento simples (
<elem></elem> ou
<elem/>), é chamado o
callback StartElement e imediatamente o
callback EndElement.
CharacterData é chamado quando é encontrada uma
string CDATA (conteúdo de um elemento). A função recebe dois argumentos:
parser e
string (o texto).
Parser
O
parser é criado pela função
lxp.new(), que recebe a tabela de
callbacks como parâmetro.
O
parser possui diversos métodos, sendo os principais
parse() (que processa uma
string como parte do documento XML) e
close() (método de chamada obrigatória que fecha o
parser).
O método
parse() deve ser chamado sem parâmetros para indicar o fim do documento.
A cada chamada de
parse() são retornados cinco valores:
true se correu bem ou nil se ocorreu algum erro; nil se correu bem ou uma mensagem de erro no caso de erro; - número da linha ou
nil; - número da coluna ou
nil; - posição absoluta ou
nil;
A última chamada (sem parâmetros) retornará
true se a estrutura XML estiver bem formada ou
nil e uma mensagem de erro se tiver ocorrido algum erro em algum momento.
Vamos a um
exemplo:
require "lxp"
local fd, l, st, erro
local contador = 0
local p = lxp.new {
StartElement = function (self, nome, atributos)
io.write("+ ", (" "):rep(contador), nome, "\n")
contador = contador + 1
end,
EndElement = function (self, nome)
contador = contador - 1
io.write("- ", (" "):rep(contador), nome, "\n")
end,
CharacterData = function (self, texto)
io.write("* ", (" "):rep(contador + 1), texto, "\n")
end,
}
-- O Leonardo percebeu um erro meu aqui: é arg, não argv
fd = io.input(arg[1])
for l in fd:lines() do
p:parse(l .. "\n")
end
fd:close()
st, erro = p:parse()
p:close()
if not st then
print("Ocorreu o seguinte erro:", erro)
end
Salve este código no arquivo
xmlparser.lua. Pegue um arquivo XML qualquer e execute:
bash$ lua xmlparser.lua nome-do-arquivo.xml
Se não houver nenhum disponível, use este:
<?xml version="1.0"?>
<elem1>
texto
<elem2/>
mais texto
</elem1>
Para saber mais:
LuaExpat.
[]'s
Rodrigo Cacilhas