En los artículos anteriores dedicados al tratamiento de XML en aplicaciones Android (parte 1, parte 2, parte 3) dentro de nuestro tutorial de programación Android hemos comentado ya los modelos SAX y DOM, los dos métodos más comunes de lectura de XML soportados en la plataforma.
En este cuarto artículo nos vamos a centrar en el último método menos conocido, aunque igual de válido según el contexto de la aplicación, llamado XmlPull. Este método es una versión similar al modelo StAX (Streaming API for XML), que en esencia es muy parecido al modelo SAX ya comentado. Y digo muy parecido porque también se basa en definir las acciones a realizar para cada uno de los eventos generados durante la lectura secuencial del documento XML. ¿Cuál es la diferencia entonces?
La diferencia radica principalmente en que, mientras que en SAX no teníamos control sobre la lectura del XML una vez iniciada (el parser lee automáticamente el XML de principio a fin generando todos los eventos necesarios), en el modelo XmlPull vamos a poder guiar o intervenir en la lectura del documento, siendo nosotros los que vayamos pidiendo de forma explícita la lectura del siguiente elemento del XML y respondiendo al resultado ejecutando las acciones oportunas.
Veamos cómo podemos hacer esto:
public class RssParserPull
{
private URL rssUrl;
public RssParserPull(String url)
{
try
{
this.rssUrl = new URL(url);
}
catch (MalformedURLException e)
{
throw new RuntimeException(e);
}
}
public List<Noticia> parse()
{
List<Noticia> noticias = null;
XmlPullParser parser = Xml.newPullParser();
try
{
parser.setInput(this.getInputStream(), null);
int evento = parser.getEventType();
Noticia noticiaActual = null;
while (evento != XmlPullParser.END_DOCUMENT)
{
String etiqueta = null;
switch (evento)
{
case XmlPullParser.START_DOCUMENT:
noticias = new ArrayList<Noticia>();
break;
case XmlPullParser.START_TAG:
etiqueta = parser.getName();
if (etiqueta.equals("item"))
{
noticiaActual = new Noticia();
}
else if (noticiaActual != null)
{
if (etiqueta.equals("link"))
{
noticiaActual.setLink(parser.nextText());
}
else if (etiqueta.equals("description"))
{
noticiaActual.setDescripcion(parser.nextText());
}
else if (etiqueta.equals("pubDate"))
{
noticiaActual.setFecha(parser.nextText());
}
else if (etiqueta.equals("title"))
{
noticiaActual.setTitulo(parser.nextText());
}
else if (etiqueta.equals("guid"))
{
noticiaActual.setGuid(parser.nextText());
}
}
break;
case XmlPullParser.END_TAG:
etiqueta = parser.getName();
if (etiqueta.equals("item") && noticiaActual != null)
{
noticias.add(noticiaActual);
}
break;
}
evento = parser.next();
}
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
return noticias;
}
private InputStream getInputStream()
{
try
{
return rssUrl.openConnection().getInputStream();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
}
Centrándonos una vez más en el método parse(), vemos que tras crear el nuevo parser XmlPull y establecer el fichero de entrada en forma de stream [mediante XmlPull.newPullParser() y parser.setInput(...)] nos metemos en un buble en el que iremos solicitando al parser en cada paso el siguiente evento encontrado en la lectura del XML, utilizando para ello el método parser.next(). Para cada evento devuelto como resultado consultaremos su tipo mediante el método parser.getEventType() y responderemos con las acciones oportunas según dicho tipo (START_DOCUMENT, END_DOCUMENT, START_TAG, END_TAG). Una vez identificado el tipo concreto de evento, podremos consultar el nombre de la etiqueta del elemento XML mediante parser.getName() y su texto correspondiente mediante parser.nextText(). En cuanto a la obtención del texto, con este modelo tenemos la ventaja de no tener que preocuparnos por “recolectar” todos los fragmentos de texto contenidos en el elemento XML, ya que nextText() devolverá todo el texto que encuentre hasta el próximo evento de fin de etiqueta (ENT_TAG).
Y sobre este modelo de tratamiento no queda mucho más que decir, ya que las acciones ejecutadas en cada caso son análogas a las que ya vimos en los artículos anteriores.
El código fuente completo de este artículo podéis descargarlo pulsando aquí.
Espero haber sido capaz de mostrar con claridad en estos cuatro artículos todas las posibilidades existentes a la hora de leer y procesar documentos XML en aplicaciones Android.
Curso de Programación Android en PDF
¿Te ha sido de utilidad el Curso de Programación Android? ¿Quieres colaborar de forma económica con el proyecto? Puedes contribuir con cualquier cantidad, unos céntimos, unos euros, cualquier aportación será bienvenida. Además, si tu aportación es superior a una pequeña cantidad simbólica recibirás como agradecimiento un documento con la última versión del curso disponible en formato PDF. Sea como sea, muchas gracias por colaborar!
Más información:
Gracias por el curso,voy a ponerme a ello.
Hola! Gracias por el tuto!
La duda que tengo es que si mi servicio web me envia el xml como una srting, como lo trato?
Porqué tu siempre pones cogiendo de una dirección.
A ver si me ayudas! Gracias! ;)
Me pasa lo mismo que a Jaume.
Si tienes un string, tienes que modificar
parser.setInput(this.getInputStream(), null);
por:
parser.setInput(new StringReader(String_en_xml));
Hola, perfecto tuto! Pero podrias poner un ejemplo de como mostra los datos en pantalla (con cualquier de los 4 métodos)
Gracias