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