Inicio Android Tratamiento de XML en Android (IV): XmlPull

Tratamiento de XML en Android (IV): XmlPull

por sgoliver

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.

Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la página del curso en GitHub.

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

Este curso también está disponible en PDF. Descubre cómo conseguirlo…

¿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:

También te puede interesar

13 comentarios

Tweets that mention Tratamiento de XML en Android (IV): XmlPull | sgoliver.net blog -- Topsy.com 25/01/2011 - 13:50

[…] This post was mentioned on Twitter by Babelias, Salva. Salva said: Último artículo sobre tratamiento de XML en #Android, esta vez para describir el modelo XmlPull [http://www.sgoliver.net/blog/?p=1604] […]

Responder
Juan 28/01/2011 - 21:49

Gracias por el curso,voy a ponerme a ello.

Responder
Desarrollo en Android | sgoliver.net blog 07/02/2011 - 11:26

[…] Tratamiento de XML en Android (IV): XmlPull […]

Responder
Jaume 18/10/2011 - 12:01

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! ;)

Responder
Alex 03/11/2011 - 11:31

Me pasa lo mismo que a Jaume.

Responder
Alternativas para leer y escribir XML (y otros ficheros) en Android | sgoliver.net blog 23/01/2012 - 17:49

[…] ya algún tiempo dedicamos varios artículos (I, II, III, IV) al tratamiento de ficheros XML en Android y vimos varias alternativas a la hora de leer (parsear) […]

Responder
Fran 15/10/2012 - 15:29

Si tienes un string, tienes que modificar

parser.setInput(this.getInputStream(), null);

por:

parser.setInput(new StringReader(String_en_xml));

Responder
Carlos 24/04/2013 - 17:07

Hola, perfecto tuto! Pero podrias poner un ejemplo de como mostra los datos en pantalla (con cualquier de los 4 métodos)

Gracias

Responder
Nelson 08/05/2014 - 19:47

Amigos, la parte del input ya no es compatible con 4.1

parser.setInput(getInputStream(),null);
parser.setInput(new InputStreamReader(getInputStream()));

lo ha revisado?

Responder
admin 09/05/2014 - 10:03

Hola Nelson, no entiendo exactamente cuál es tu problema ¿te aparece algún error concreto?

Responder
Hugo 30/09/2014 - 20:22

El parser me lanza el siguiente error:
09-30 11:04:18.569: W/System.err(3987): org.apache.harmony.xml.ExpatParser$ParseException: At line 8, column 6: junk after document element
en el caso de que el XML tenga mas de un elemento. Por ejemplo:

Juan
18

Pedro
21

Cuando solo tiene un elemento me parsea sin problema. Ejemplo:

Pedro
21

Responder
Curso Programación Android por Salvador Gómez – Indice de Contenidos | Miguel Moyetones 17/06/2015 - 21:25

[…] Tratamiento de XML en Android (IV): XmlPull [v3] […]

Responder
Johan Vasquez 05/01/2017 - 3:37

Buena noches te felicito excelente post. Tengo varios archivos xml que debo cargar en la base datos interna del móvil. Entre los archivo tengo data que puede variar en un promedio de 3000 a 70000 registros, ¿Cuál de lo métodos que has trabajado consideras el más veloz?.

Antemano. Muchas Gracias por tiempo

Responder

Dejar un comentario

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información. Aceptar Más Información

Política de Privacidad y Cookies