Parseando um XML com o SAX
em 09/10/2002
, por Guilherme Silveira
Então abrimos o arquivo XML para leitura:
Uma vez que a API do Sax é orientada a eventos, criamos um objeto que lida com os eventos e dizemos ao parser para utilizar esse Handler durante o parsing do arquivo xml.
Observação: caso você queira utilizar um parser de XML que monte uma árvore com todo o XML, você deve usar um parser do tipo DOM. Lembre-se que o DOM coloca tudo em memória, o que pode não ser eficiente para XMLs grandes (em business to business, XMLs chegam a 500 megabytes). Agora falta criar a nossa classe XMLHandler. Ela vai recebendo chamadas de método a medida que o arquivo XML é parseado pelo SAXParser.
Então implementamos os métodos que serão chamados no começo e fim do documento:
Dica: Neste momento você pode finalizar algum processo com os dados que processou do arquivo inteiro.
E o método que trata o fim de uma Tag, onde mostramos o valor interno da Tag, limpamos ele e setamos o galhoAtual novamente.
Por fim precisamos implementar o método que trata os valores internos das Tags, que adiciona esse valor para o valorAtual, uma vez que essa função pode ser chamada infinitas vezes dentro de uma tag. Isto é, se você tem um XML deste tipo:
Pode ser (não necessariamente), que você receba duas chamadas para o characters(): uma para "gui", e outra para " lherme", por exemplo. Isto acontece devido a otimização da API. Dica: A utilização de um StringBuffer é sempre melhor, uma vez que buffers trabalham muito mais rápido que Strings.
O arquivo java que acompanha o tutorial pode ser compilado e rodado assim:
Utilize-o para ver realmente como o SAX funciona. Dentro do .zip tem 2 arquivos XML de exemplo.
Arquivos Xml e Sax
Este tutorial visa ensinar a usar a api chamada de SAX, Simple Api for XML, que vem junto com o Java 1.4 e, portanto, você deve ter esta versão do SDK instalado.
Percorrida estas páginas, voce será capaz ler um arquivo XML e usar os dados que lhe interessa. É necessário que você saiba o que é XML e para que você vai utilizá-lo.
SAX e suas implementações: SAX é um conjunto de interfaces (uma api) que deve ser implementada para efetuar o parsing de arquivos xml. No momento o Java 1.4 ja vem com implementações da api SAX. Você pode encontrar, por exemplo, o Xerces e o Crimson do projeto jakarta e instalá-los separadamente caso possua uma versão anterior do java, porém precisará adaptar um pouco mais o código, que vai alem do objetivo desse tutorial.
O Parser
Para criar um objeto parser, utilizamos uma API da Sun que procura um parser adequado.
Então abrimos o arquivo XML para leitura:
Uma vez que a API do Sax é orientada a eventos, criamos um objeto que lida com os eventos e dizemos ao parser para utilizar esse Handler durante o parsing do arquivo xml.
Observação: caso você queira utilizar um parser de XML que monte uma árvore com todo o XML, você deve usar um parser do tipo DOM. Lembre-se que o DOM coloca tudo em memória, o que pode não ser eficiente para XMLs grandes (em business to business, XMLs chegam a 500 megabytes). Agora falta criar a nossa classe XMLHandler. Ela vai recebendo chamadas de método a medida que o arquivo XML é parseado pelo SAXParser.
XMLHandler
As classes que lidam com os eventos da api do SAX devem extender a DefaultHandler.
Quem já trabalhou com apis de GUI tanto em C/C++, Visual Basic ou Java (swing/awt), sabe como uma API orientada a eventos funciona e tera mais facilidade para entender o funcionamento dessa classe que criaremos. Durante o parsing do XML, esta nossa classe receberá chamadas, de acordo com o que o parser encontrar!
A classe DefaultHandler tem os métodos startDocument, endDocument, startElement, endElement e characters sendo chamadas quando um documento comeca e termina, quando um elemento (tag) comeca e termina e quando algum texto eh encontrado em um elemento (tag).
Nota: O estranho, e o que torna a api do SAX rápida, é que o método characters pode ser chamado mais de uma vez pra mesma TAG. Isso acontece, por exemplo, quando o arquivo xml possui código unicode.
Devido a esse detalhe do método characters devemos entao manter uma variável local a classe, que se preenche a cada chamada deste método, e é liberada no momento que o método endElement eh chamado, daremos o nome de valorAtual a ela.
Temos também que manter uma variável com o "endereço" atual do parser na estrutura do arquivo XML, isto é, quando o arquivo estiver dentro da tag Compra->Produtos->Produto devemos saber que ele esta nesse tag, e não no Venda->Produtos->Produto. Portanto não adianta checarmos se uma tag possui o nome que desejamos, mas precisamos sim é checar se o "endereço" atual no arquivo xml é o que procuramos. Para isso criamos a variável galhoAtual contendo o galho de parsing atual.
Então implementamos os métodos que serão chamados no começo e fim do documento:
Dica: Neste momento você pode finalizar algum processo com os dados que processou do arquivo inteiro.
Parseando as tags
Agora implementamos o método que marca o início de uma nova Tag, primeiro setando o galhoAtual para seu novo valor e limpando o valorAtual.
Então imprimimos o nome do galho atual para ter alguma saáda do programa.
E o método que trata o fim de uma Tag, onde mostramos o valor interno da Tag, limpamos ele e setamos o galhoAtual novamente.
Por fim precisamos implementar o método que trata os valores internos das Tags, que adiciona esse valor para o valorAtual, uma vez que essa função pode ser chamada infinitas vezes dentro de uma tag. Isto é, se você tem um XML deste tipo:
Pode ser (não necessariamente), que você receba duas chamadas para o characters(): uma para "gui", e outra para " lherme", por exemplo. Isto acontece devido a otimização da API. Dica: A utilização de um StringBuffer é sempre melhor, uma vez que buffers trabalham muito mais rápido que Strings.
O arquivo java que acompanha o tutorial pode ser compilado e rodado assim:
Utilize-o para ver realmente como o SAX funciona. Dentro do .zip tem 2 arquivos XML de exemplo.