kXML - Fazendo parser de um XML com J2ME

Aprenda neste artigo o que é o kXML, e saiba como utiliza-lo com J2ME.

kXML - Fazendo parser de um XML com J2ME

 

O kXML é um parser de XML estável e otimizado, para ser utilizado em pequenos dispositivos com recursos limitados de memória e processamento, e desta forma sendo ideal para ser utilizado com J2ME.

 

Existem algumas técnicas conhecidas para realizar o parser de um XML. Uma das mais utilizadas é o DOM, que utiliza um modelo baseado em árvore, criando uma estrutura de dados na memória, onde é possível acessar essa estrutura através de um conjunto de objetos. O DOM é muito simples de utilizar, mas sendo que muitos objetos são armazenados em memória, ele não é recomendado para ser utilizado com J2ME.

 

Outra técnica conhecida é chamada de “push parser”, que é orientada a eventos, onde ao ler um XML, um objeto “listener” é notificado sempre que novas tags são encontradas. Esta forma é como o popular SAX trabalha.

 

O kXML utiliza um outro modelo, conhecido como “pull parser”, onde uma pequena quantidade de dados é analisada de cada vez. A aplicação faz o parser do XML solicitando sempre a próxima parte que deve ser processada, isto geralmente é feito em um loop até o fim do XML. Desta forma, a aplicação pode exibir as informações do XML a medida que o parser é efetuado, como  por exemplo, ao fazer um download de um arquivo do servidor. Já um parser que utiliza DOM, precisaria ler o documento inteiro para montar uma estrutura de árvores, para somente depois exibir as informações.


Fazendo o download

A versão utilizada neste artigo é a 2.2.2:

http://prdownloads.sourceforge.net/kxml/kxml2-min-2.2.2.jar?download

 

Exemplo do arquivo XML

Neste artigo vamos criar um simples Midlet, que vai fazer o parser do arquivo XML abaixo, e exibirá os dados na tela.

 

 

Código fonte do Midlet<SPAN ></SPAN>

<SPAN >O código fonte do Midlet é muito simples. O código abre uma InputStream para o XML exibido anteriormente, que</SPAN> é utilizada para criar uma instância de <B ><SPAN >org.kxml2.io.KXmlParser.</SPAN></B>

 

Os métodos <B ><SPAN >require()</SPAN></B> e <B ><SPAN >nextTag()</SPAN></B> são utilizados para percorrer o XML. O método <B ><SPAN >nextTag()</SPAN></B> obviamente retorna a próxima tag e o método require() obriga o parser a posicionar o “cursor” na posição desejada. A medida que o parser é realizado, os dados <SPAN >das pessoas existentes são exibidas na tela do dispositivo.</SPAN>

<SPAN > </SPAN>

<SPAN lang=EN-US >package javamagazine;</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >import …</SPAN>

<SPAN lang=EN-US >import org.kxml2.io.KXmlParser;</SPAN>

<SPAN lang=EN-US >import org.xmlpull.v1.XmlPullParser;</SPAN>

<SPAN lang=EN-US >import org.xmlpull.v1.XmlPullParserException;</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >public class XMLParserMidlet extends MIDlet {</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >Form form = new Form("Pessoas");</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >protected void startApp() throws MIDletStateChangeException {</SPAN>

<SPAN lang=EN-US >InputStream in = getClass().getResourceAsStream("pessoas.xml");</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >try {</SPAN>

<SPAN lang=EN-US >Display.getDisplay(this).setCurrent(form);</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >parser(in);</SPAN>

<SPAN lang=EN-US >} catch (Exception e) {</SPAN>

<SPAN lang=EN-US >e.printStackTrace();</SPAN>

<SPAN lang=EN-US >}</SPAN>

<SPAN lang=EN-US >}</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >private void parser(InputStream in) throws Exception {</SPAN>

<SPAN lang=EN-US ></SPAN><SPAN >//Inicia o XMLParser</SPAN>

<SPAN >KXmlParser parser = new KXmlParser();</SPAN>

<SPAN ></SPAN><SPAN lang=EN-US >parser.setInput(new InputStreamReader(in));</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US ></SPAN><SPAN >parser.nextTag();</SPAN>

<SPAN > </SPAN>

<SPAN >//Posiciona na tag <agenda></SPAN>

<SPAN ></SPAN><SPAN lang=EN-US >parser.require(XmlPullParser.START_TAG, null, "agenda");</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US ></SPAN><SPAN >//Enquanto é diferente de END_TAG</SPAN>

<SPAN ></SPAN><SPAN lang=EN-US >while (parser.nextTag () != XmlPullParser.END_TAG)</SPAN>

<SPAN lang=EN-US ></SPAN><SPAN >{</SPAN>

<SPAN ><SPAN >   </SPAN>//Posiciona na tag <pessoa></SPAN>

<SPAN ><SPAN >   </SPAN>parser.require(XmlPullParser.START_TAG, null, "pessoa");</SPAN>

<SPAN > </SPAN>

<SPAN ><SPAN >   </SPAN>parserPessoa(parser);</SPAN>

<SPAN > </SPAN>

<SPAN ><SPAN >   </SPAN>form.append("\n");</SPAN>

<SPAN > </SPAN>

<SPAN ></SPAN><SPAN lang=EN-US >parser.require(XmlPullParser.END_TAG, null, "pessoa");</SPAN>

<SPAN lang=EN-US >}</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >parser.require(XmlPullParser.END_TAG, null, "agenda");</SPAN>

<SPAN lang=EN-US >parser.next();</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >parser.require(XmlPullParser.END_DOCUMENT, null, null);</SPAN>

<SPAN lang=EN-US >}</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >private void parserPessoa(KXmlParser parser) throws Exception {</SPAN>

<SPAN lang=EN-US ></SPAN><SPAN >//Enquanto é diferente de </pessoa></SPAN>

<SPAN ></SPAN><SPAN lang=EN-US >while (parser.nextTag() != XmlPullParser.END_TAG) {</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US ></SPAN><SPAN >//Posiciona em uma tag "START". Ex: <nome> ou <fone></SPAN>

<SPAN >parser.require(XmlPullParser.START_TAG, null, null);</SPAN>

<SPAN > </SPAN>

<SPAN ></SPAN><SPAN lang=EN-US >String name = parser.getName();</SPAN>

<SPAN lang=EN-US >String text = parser.nextText();</SPAN>

<SPAN lang=EN-US >System.out.println("Tag: " + name + " -> " + text);</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US ></SPAN><SPAN >//Adiciona o texto no Form</SPAN>

<SPAN >form.append(text);</SPAN>

<SPAN > </SPAN>

<SPAN >//Posiciona no fim da tag </nome> ou </fone></SPAN>

<SPAN ></SPAN><SPAN lang=EN-US >parser.require(XmlPullParser.END_TAG, null, name);</SPAN>

<SPAN lang=EN-US >}</SPAN>

<SPAN lang=EN-US >}</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >pauseApp…</SPAN>

<SPAN lang=EN-US > </SPAN>

<SPAN lang=EN-US >destroyApp…</SPAN>

<SPAN lang=EN-US >}</SPAN><SPAN ></SPAN>

<SPAN > </SPAN>

<SPAN >Ao executar o exemplo, a seguinte tela vai aparecer:</SPAN>

 

Entendendo o exemplo<SPAN ></SPAN>

<SPAN >O código abre uma InputStream utilizando o método </SPAN>getResourceAsStream(), mas em uma aplicação real provavelmente o XML seria obtido através de uma conexão Http ou um socket<SPAN >:</SPAN>

<SPAN > </SPAN>

InputStream in = getClass().getResourceAsStream("pessoas.xml");

<SPAN lang=EN-US > </SPAN>

<SPAN >Depois de abrir uma InputStream, pode-se criar uma instância da classe KXmlParser conforme mostrado abaixo:</SPAN>

<SPAN > </SPAN>

InputStream in = ….

 

KXmlParser parser = new KXmlParser();

parser.setInput(new InputStreamReader(in));

 

O próximo passo é chamar o método require() para posicionar o parser na tag desejada, neste caso: <agenda>.

 

parser.require(XmlPullParser.START_TAG, null, "agenda");

 

Para ler todas as pessoas, o método require(“pessoa”) é chamado sucessivamente para buscar a próxima tag <pessoa> que deve ser processada, até encontrar o fim da tag </agenda>.

 

while (parser.nextTag () != XmlPullParser.END_TAG)

{

//Posiciona na tag <pessoa>

parser.require(XmlPullParser.START_TAG, null, "pessoa");

 

parserPessoa(parser);

 

form.append("\n");

 

parser.require(XmlPullParser.END_TAG, null, "pessoa");

}

 

Para cada tag <pessoa> encontrada, o método parserPessoa(parser) é chamado para ler os seus elementos.

 

Note que dentro do loop, o método “parser.require(XmlPullParser.START_TAG, null, null);” é chamado para posicionar o cursor na próxima tag <nome> ou <fone>, para posteriormente obter o conteúdo deste elemento utilizando o método parser.nextText().

 

private void parserPessoa(KXmlParser parser) throws Exception {

//Enquanto é diferente de </pessoa>

while (parser.nextTag() != XmlPullParser.END_TAG) {

 

//Posiciona em uma tag "START". Ex: <nome> ou <fone>

parser.require(XmlPullParser.START_TAG, null, null);

 

String text = parser.nextText();

 

form.append(text);

 

//Posiciona no fim da tag </nome> ou </fone>

parser.require(XmlPullParser.END_TAG, null, name);

}

}

 

Conclusão

Neste artigo foi demonstrado como fazer um parser de um XML, utilizando o kXML, uma API simples e otimizada, ideal para ser utilizada com J2ME.

 

Espero que tenham gostado e até a próxima.

Artigos relacionados