Inicio Android Tratamiento de XML en Android (I): SAX

Tratamiento de XML en Android (I): SAX

por sgoliver

En los siguientes artículos de este Tutorial de Desarrollo para Android vamos a comentar las distintas posibilidades que tenemos a la hora de trabajar con datos en formato XML desde la plataforma Android.

A día de hoy, en casi todas las grandes plataformas de desarrollo existen varias formas de leer y escribir datos en formato XML. Los dos modelos más extendidos son SAX (Simple API for XML) y DOM (Document Object Model). Posteriormente, han ido apareciendo otros tantos, con más o menos éxito, entre los que destaca StAX (Streaming API for XML). Pues bien, Android no se queda atrás en este sentido e incluye estos tres modelos principales para el tratamiento de XML, o para ser más exactos, los dos primeros como tal y una versión análoga del tercero (XmlPull). Por supuesto con cualquiera de los tres modelos podemos hacer las mismas tareas, pero ya veremos cómo dependiendo de la naturaleza de la tarea que queramos realizar va a resultar más eficiente utilizar un modelo u otro.

Antes de empezar, unas anotaciones respecto a los ejemplos que voy a utilizar. Estas técnicas se pueden utilizar para tratar cualquier documento XML, tanto online como local, pero por utilizar algo conocido por la mayoría de vosotros todos los ejemplos van a trabajar sobre los datos XML de un documento RSS online, y en mi caso utilizaré como ejemplo el canal RSS de portada de europapress.com.

Un documento RSS de este feed tiene la estructura siguiente:

<rss version="2.0">
    <channel>
        <title>Europa Press</title>
        <link>http://www.europapress.es/</link>
        <description>Noticias de Portada.</description>
        <image>
            <url>http://s01.europapress.net/eplogo.gif</url>
            <title>Europa Press</title>
            <link>http://www.europapress.es</link>
        </image>
        <language>es-ES</language>
        <copyright>Copyright</copyright>
        <pubDate>Sat, 25 Dec 2010 23:27:26 GMT</pubDate>
        <lastBuildDate>Sat, 25 Dec 2010 22:47:14 GMT</lastBuildDate>
        <item>
            <title>Título de la noticia 1</title>
            <link>http://link_de_la_noticia_2.es</link>
            <description>Descripción de la noticia 2</description>
            <guid>http://identificador_de_la_noticia_2.es</guid>
            <pubDate>Fecha de publicación 2</pubDate>
        </item>
        <item>
            <title>Título de la noticia 2</title>
            <link>http://link_de_la_noticia_2.es</link>
            <description>Descripción de la noticia 2</description>
            <guid>http://identificador_de_la_noticia_2.es</guid>
            <pubDate>Fecha de publicación 2</pubDate>
        </item>
        ...
    </channel>
</rss>

Como puede observarse, se compone de un elemento principal <channel> seguido de varios datos relativos al canal y posteriormente una lista de elementos <item> para cada noticia con sus datos asociados.

En estos artículos vamos a describir cómo leer este XML mediante cada una de las tres alternativas citadas, y para ello lo primero que vamos a hacer es definir una clase java para almacenar los datos de una noticia. Nuestro objetivo final será devolver una lista de objetos de este tipo, con la información de todas las noticias. Por comodidad, vamos a almacenar todos los datos como cadenas de texto:

public class Noticia {
    private String titulo;
    private String link;
    private String descripcion;
    private String guid;
    private String fecha;

    public String getTitulo() {
        return titulo;
    }

    public String getLink() {
        return link;
    }

    public String getDescripcion() {
        return descripcion;
    }

    public String getGuid() {
        return guid;
    }

    public String getFecha() {
        return fecha;
    }

    public void setTitulo(String t) {
        titulo = t;
    }

    public void setLink(String l) {
        link = l;
    }

    public void setDescripcion(String d) {
        descripcion = d;
    }

    public void setGuid(String g) {
        guid = g;
    }

    public void setFecha(String f) {
        fecha = f;
    }
}

Una vez conocemos la estructura del XML a leer y hemos definido las clases auxiliares que nos hacen falta para almacenar los datos, pasamos ya a comentar el primero de los modelos de tratamiento de XML.

SAX en Android

En el modelo SAX, el tratamiento de un XML se basa en un analizador (parser) que a medida que lee secuencialmente el documento XML va generando diferentes eventos con la información de cada elemento leido. Asi, por ejemplo, a medida que lee el XML, si encuentra el comienzo de una etiqueta <title> generará un evento de comienzo de etiqueta, startElement(), con su información asociada, si después de esa etiqueta encuentra un fragmento de texto generará un evento characters() con toda la información necesaria, y así sucesivamente hasta el final del documento. Nuestro trabajo consistirá por tanto en implementar las acciones necesarias a ejecutar para cada uno de los eventos posibles que se pueden generar durante la lectura del documento XML.

Los principales eventos que se pueden producir son los siguientes (consultar aquí la lista completa):

  • startDocument(): comienza el documento XML.
  • endDocument(): termina el documento XML.
  • startElement(): comienza una etiqueta XML.
  • endElement(): termina una etiqueta XML.
  • characters(): fragmento de texto.

Todos estos métodos están definidos en la clase org.xml.sax.helpers.DefaultHandler, de la cual deberemos derivar una clase propia donde se sobrescriban los eventos necesarios. En nuestro caso vamos a llamarla RssHandler.

public class RssHandler extends DefaultHandler {
    private List<Noticia> noticias;
    private Noticia noticiaActual;
    private StringBuilder sbTexto;

    public List<Noticia> getNoticias(){
        return noticias;
    }

    @Override
    public void characters(char[] ch, int start, int length)
                   throws SAXException {

        super.characters(ch, start, length);

        if (this.notciaActual != null)
            builder.append(ch, start, length);
    }

    @Override
    public void endElement(String uri, String localName, String name)
                   throws SAXException {

        super.endElement(uri, localName, name);

        if (this.notciaActual != null) {

            if (localName.equals("title")) {
                noticiaActual.setTitulo(sbTexto.toString());
            } else if (localName.equals("link")) {
                noticiaActual.setLink(sbTexto.toString());
            } else if (localName.equals("description")) {
                noticiaActual.setDescripcion(sbTexto.toString());
            } else if (localName.equals("guid")) {
                noticiaActual.setGuid(sbTexto.toString());
            } else if (localName.equals("pubDate")) {
                noticiaActual.setFecha(sbTexto.toString());
            } else if (localName.equals("item")) {
                noticias.add(noticiaActual);
            }

            sbTexto.setLength(0);
        }
    }

    @Override
    public void startDocument() throws SAXException {

        super.startDocument();

        noticias = new ArrayList<Noticia>();
        sbTexto = new StringBuilder();
    }

    @Override
    public void startElement(String uri, String localName,
                   String name, Attributes attributes) throws SAXException {

        super.startElement(uri, localName, name, attributes);

        if (localName.equals("item")) {
            noticiaActual = new Noticia();
        }
    }
}

Como se puede observar en el código de anterior, lo primero que haremos será incluir como miembro de la clase la lista de noticias que pretendemos construir, List<Noticia> noticias, y un método getNoticias() que permita obtenerla tras la lectura completa del documento. Tras esto, implementamos directamente los eventos SAX necesarios.

Comencemos por startDocument(), este evento indica que se ha comenzado a leer el documento XML, por lo que lo aprovecharemos para inicializar la lista de noticias y las variables auxiliares.

Tras éste, el evento startElement() se lanza cada vez que se encuentra una nueva etiqueta de apertura. En nuestro caso, la única etiqueta que nos interesará será <item>, momento en el que inicializaremos un nuevo objeto auxiliar de tipo Noticia donde almacenaremos posteriormente los datos de la noticia actual.

El siguiente evento relevante es characters(), que se lanza cada vez que se encuentra un fragmento de texto en el interior de una etiqueta. La técnica aquí será ir acumulando en una variable auxiliar, sbTexto, todos los fragmentos de texto que encontremos hasta detectarse una etiqueta de cierre.

Por último, en el evento de cierre de etiqueta, endElement(), lo que haremos será almacenar en el atributo apropiado del objeto noticiaActual (que conoceremos por el parámetro localName devuelto por el evento) el texto que hemos ido acumulando en la variable sbTexto y limpiaremos el contenido de dicha variable para comenzar a acumular el siguiente dato. El único caso especial será cuando detectemos el cierre de la etiqueta <item>, que significará que hemos terminado de leer todos los datos de la noticia y por tanto aprovecharemos para añadir la noticia actual a la lista de noticias que estamos construyendo.

Una vez implementado nuestro handler, vamos a crear una nueva clase que haga uso de él para parsear mediante SAX un documento XML concreto. A esta clase la llamaremos RssParserSax. Más adelante crearemos otras clases análogas a ésta que hagan lo mismo pero utilizando los otros dos métodos de tratamiento de XML ya mencionados. Esta clase tendrá únicamente un constructor que reciba como parámetro la URL del documento a parsear, y un método público llamado parse() para ejecutar la lectura del documento, y que devolverá como resultado una lista de noticias. Veamos cómo queda esta clase:

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import java.net.URL;
import javax.xml.parsers.SAXParser;
import java.net.MalformedURLException;
import javax.xml.parsers.SAXParserFactory;

public class RssParserSax
{
	private URL rssUrl;

	public RssParserSax(String url)
 	{
 		try
 		{
 			this.rssUrl = new URL(url);
 		}
 		catch (MalformedURLException e)
 		{
 			throw new RuntimeException(e);
 		}
 	}

 	public List<Noticia> parse()
 	{
 		SAXParserFactory factory = SAXParserFactory.newInstance();

 		try
 		{
 			SAXParser parser = factory.newSAXParser();
 			RssHandler handler = new RssHandler();
 			parser.parse(this.getInputStream(), handler);
 			return handler.getNoticias();
 		}
 		catch (Exception e)
 		{
 			throw new RuntimeException(e);
 		}
 	}

 	private InputStream getInputStream()
 	{
 		try
 		{
 			return rssUrl.openConnection().getInputStream();
 		}
 		catch (IOException e)
 		{
 			throw new RuntimeException(e);
 		}
	}
}

Como se puede observar en el código anterior, el constructor de la clase se limitará a aceptar como parámetro la URL del documento XML a parsear  a controlar la validez de dicha URL, generando una excepción en caso contrario.

Por su parte, el método parse() será el encargado de crear un nuevo parser SAX mediante sú fábrica correspondiente [lo que se consigue obteniendo una instancia de la fábrica con SAXParserFactory.newInstance() y creando un nuevo parser con factory.newSaxParser()] y de iniciar el proceso pasando al parser una instancia del handler que hemos creado anteriormente y una referencia al documento a parsear en forma de stream.

Para esto último, nos apoyamos en un método privado auxiliar getInputStream(), que se encarga de abrir la conexión con la URL especificada [mediante openConnection()] y obtener el stream de entrada [mediante getInputStream()].

Con esto ya tenemos nuestra aplicación Android preparada para parsear un documento XML online utilizando el modelo SAX. Veamos lo simple que sería ahora llamar a este parser por ejemplo desde nuestra actividad principal. Como ejemplo de tratamiento de los datos obtenidos mostraremos los titulares de las noticias en un cuadro de texto (txtResultado):

public void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);

     RssParserSax saxparser =
            new RssParserSax("http://www.europapress.es/rss/rss.aspx");

     List<Noticia> noticias = saxparser.parse();

     //Tratamos la lista de noticias
     //Por ejemplo: escribimos los títulos en pantalla
     txtResultado.setText("");
     for(int i=0; i<noticias.size(); i++)
     {
          txtResultado.setText(
      		txtResultado.getText().toString() +
		System.getProperty("line.separator") +
		noticias.get(i).getTitulo());
     }
}

Las lineas 6 y 9 del código anterior son las que hacen toda la magia. Primero creamos el parser SAX pasándole la URL del documento XML y posteriormente llamamos al método parse() para obtener una lista de objetos de tipo Noticia que posteriormente podremos manipular de la forma que queramos. Así de sencillo.

Adicionalmente, para que este ejemplo funcione debemos añadir previamente permisos de acceso a internet para la aplicación. Esto se hace en el fichero AndroidManifest.xml, que quedaría de la siguiente forma:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="net.sgoliver"
      android:versionCode="1"
      android:versionName="1.0">

    <uses-permission
        android:name="android.permission.INTERNET" />

    <application android:icon="@drawable/icon"
                     android:label="@string/app_name">
        <activity android:name=".AndroidXml"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <uses-sdk android:minSdkVersion="7" />
</manifest>

En la linea 6 del código podéis ver cómo añadimos el permiso de acceso a la red mediante el elemento <uses-permission> con el parámetro android.permission.INTERNET

Pero hay algo más, si ejecutamos el código anterior en una versión de Android anterior a la 3.0 no tendremos ningún problema. La aplicación descargará el XML y lo parseará tal como hemos definido. Sin embargo, si utilizamos una versión de Android 3.0 o superior nos encontraremos con algo similar a esto:

Error-Android-4

Y si miramos el log de ejecución veremos que se ha generado una excepción del tipo NetworkOnMainThreadException. ¿Qué ha ocurrido? Pues bien, lo que ha ocurrido es que desde la versión 3 de Android se ha establecido una política que no permite a las aplicaciones ejecutar operaciones de larga duración en el hilo principal que puedan bloquear temporalmente la interfaz de usuario. En este caso, nosotros hemos intentado hacer una conexión a la red para descargarnos el XML y Android se ha quejado de ello generando un error.

¿Y cómo arreglamos esto? Pues la solución pasa por mover toda la lógica de descarga y lectura del XML a otro hilo de ejecución secundario, es decir, hacer el trabajo duro en segundo plano dejando libre el hilo principal de la aplicación y por tanto sin afectar a la interfaz. La forma más sencilla de hacer esto en Android es mediante la utilización de las llamadas AsyncTask o tareas asíncronas. Más adelante dedicaremos todo un capítulo a este tema, por lo que ahora no entraremos en mucho detalle y nos limitaremos a ver cómo transformar nuestro código anterior para que funcione en versiones actuales de Android.

Lo que haremos será definir una nueva clase que extienda de AsyncTask y sobrescribiremos sus métodos doInBackground() y onPostExecute(). Al primero de ellos moveremos  la descarga y parseo del XML, y al segundo las tareas que queremos realizar cuando haya finalizado el primero, en nuestro caso de ejemplo la escritura de los titulares al cuadro de texto de resultado. Quedaría de la siguiente forma:

//Tarea Asíncrona para cargar un XML en segundo plano
private class CargarXmlTask extends AsyncTask<String,Integer,Boolean> {

    protected Boolean doInBackground(String... params) {

        RssParserSax saxparser =
            new RssParserSax(params[0]);

        noticias = saxparser.parse();

        return true;
    }

    protected void onPostExecute(Boolean result) {

        //Tratamos la lista de noticias
        //Por ejemplo: escribimos los títulos en pantalla
        txtResultado.setText("");
        for(int i=0; i<noticias.size(); i++)
        {
            txtResultado.setText(
                txtResultado.getText().toString() +
                System.getProperty("line.separator") +
                noticias.get(i).getTitulo());
        }
    }
}

Por último, sustituiremos el código de nuestra actividad principal por una simple llamada para crear y ejecutar la tarea en segundo plano:

public void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);

     //Carga del XML mediante la tarea asíncrona

     CargarXmlTask tarea = new CargarXmlTask();
     tarea.execute("http://www.europapress.es/rss/rss.aspx");
}

Y ahora sí. Con esta ligera modificación del código nuestra aplicación se ejecutará correctamente en cualquier versión de Android.

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.

En los siguientes artículos veremos un modelo SAX alternativo con algunas ventajas sobre el que acabamos de comentar, y los otros dos métodos de tratamiento XML en Android indicados (DOM y StAX).

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

46 comentarios

Tratamiento de XML en Android (II): SAX Simplificado | sgoliver.net blog 19/01/2011 - 13:48

[…] el artículo anterior del tutorial vimos cómo realizar la lectura y tratamiento de un documento XML utilizando el modelo […]

Responder
Tratamiento de XML en Android (III): DOM | sgoliver.net blog 24/01/2011 - 12:54

[…] el artículo anterior del curso de programación para Android hablamos sobre SAX, el primero de los métodos disponibles […]

Responder
Tratamiento de XML en Android (IV): XmlPull | sgoliver.net blog 25/01/2011 - 12:58

[…] 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 […]

Responder
Desarrollo en Android | sgoliver.net blog 25/01/2011 - 13:01

[…] Tratamiento de XML en Android (I): SAX […]

Responder
Chucherm 10/02/2011 - 16:58

Muchas gracias por el tutorial, una pregunta a la hora de ejecutar la aplicación no me muestra los resultados en la pantalla de android, ¿Tengo que agregar algo mas en el codigo?

Responder
sgoliver 11/02/2011 - 11:53

Efectivamente, la aplicación del tutorial se limita a recuperar los datos del XML y crear la lista de objetos de tipo Noticia (todo dentro del método onCreate()), pero no los muestra en pantalla.

Si quieres mostrar los resultados en pantalla puedes revisar los artículos anteriores del tutorial para aprender por ejemplo a añadir y personalizar un control de tipo lista para mostrar los resultados del XML.

Responder
Abel 20/04/2011 - 11:42

Hola Me encantan tus tutoriales en este código lees de un fichero que esta en Internet, jo estoy empezando con Android y me gustaría saber como se puede leer de manera local es decir un fichero que este en la tarjeta de memoria del emulador para poder crear mis propias clases y practicar un poquito si me puede orientar te estaré muy agradecido. Gracias de antemano.

Responder
Jav 26/05/2011 - 16:25

Hola, bueno el post! quisiera saber como modificar el codigo para leer cada uno de los tags del xml ejemplo, no solo los que estan contenidos en item… Estoy desarrollando un app donde tengo que hacer esto y estoy teniendo problemas con los listeners…

Muchas gracias

Responder
Luis Manuel 08/07/2011 - 12:55

Buenas sgoliver,

Ante todo felicitarte por el curso, es con diferencia el mejor de la red en castellano.

Tengo una duda y espero que puedas ayudarme: necesito leer un fichero XML y mostrarlo en pantalla, pero en mi caso es un fichero local. En el post comentas que éste método es válido tanto para lectura online como offline pero no sé cómo indicarle la ruta a un fichero XML local. ¿Podrías ayudarme?

Gracias.
Saludos.

Responder
motki 12/07/2011 - 9:11

Hola, muy buen tutorial, sin embargo estoy empezando con todo esto y no sé como personalizar el control de tipo lista para mostrar los resultados ….
¿Sería mucho pedir que nos indicases cómo hacerlo?. Muchas gracias.

Responder
admin 12/07/2011 - 9:32

Hola motki, para saber cómo mostrar los resultados en una lista puedes consultar los artículos del curso dedicados a los «Controles de Selección». Saludos.

Responder
Rva 06/09/2011 - 11:25

Hola,muy buen tutorial,es lo que estaba buscando, pero tengo problemas con los acentos y la codificación al hacer la lectura.No se si es problema del xml o de que hay que especificar la codificación en codigo.¿Como se podria hacer?.Gracias de antemano

Responder
RSA 11/11/2011 - 22:59

Una pregunta, en la llamada al parser, no deberias haber inicilizado la lista de noticias??

Responder
Eloy 22/11/2011 - 17:32

Leído el articulo, veo que obtienes el fichero XML en caliente.

Estay desarrollando una pequeña aplicación, para aprender un poco en la que requiero de algun tipo de almacén de datos. He pensado en un fichero XML para no complicar de momento mucho la cosa con una bbdd.

El asunto es que en la carpeta de resources no veo claro donde debería ir un fichero de este tipo de lectura escritura y que contendría la información persistente de la aplicación.

Responder
Renzo 14/12/2011 - 0:01

Muy bien todo, pero tengo un problema, cuando la etiqueta contiene «enter» solo me lee lo que contiene la primera linea, que podria hacer?, se me ocurre que tiene que ver algo con el metodo characters(), aun asi quisiera que me ayudes. Te agradezco de antemano la ayuda…gracias

Responder
Martin 13/01/2012 - 1:20

Exelente muchas gracias…

Responder
Alternativas para leer y escribir XML (y otros ficheros) en Android | sgoliver.net blog 25/01/2012 - 9:24

[…] 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 […]

Responder
Anselmo 22/02/2012 - 22:27

Hola, muchas gracias por el tutorial, realmente me ha servido mucho. Hay un detalle que me tiene intrigado, ya que el código de ejemplo funciona muy bien si todos los campos que se leen no están vacios, pero cuando esta algún campo vacio el programa no imprime nada, ¿hay alguna solución para esto?
Gracias.

Responder
Samuel 29/02/2012 - 10:05

Como hago para añador y personalizar un control del tipo lista para mostrar un xml

Responder
Luis Avila 25/04/2012 - 17:14

Hola. Muy buenos tus tutoriales. Me encuentro con un problema. Me gustaria que en una clase java recibir un xml como los que hace eclipse y poder (desde java) pintar la pantalla con lo que me trae el xml, el xml va a ser exacto como lo pinta eclipse. Tienes alguna parte donde pueda conseguir eso?, espero pronta respuesta.

Responder
jmgarzo 02/05/2012 - 17:45

Buenísimo el artículo. Muchas gracias por hacer todo este trabajo.

Responder
David 09/05/2012 - 11:22

Buenas, si quisiera en vez de leer los nodos hijos de cada item, leer los atributos de cada item… osea:

en vez de :

Título de la noticia 1
link_de_la_noticia_2.es
Descripción de la noticia 2
identificador_de_la_noticia_2.es
Fecha de publicación 2

¿Como debería de hacerse?

Saludos.

Responder
LuTOMetal 04/07/2012 - 11:43

Primero que nada felicidades por tus tutoriales que sigo muchisimo.
He probado tus metodos de lector de xml pero me da muchos problemas en las versiones posteriores a las 3.0. Hago exactamente lo mismo. Me gustaría si pudiera ser que probarás este mismo proyecto en versiones posteriores 3.0 a ver que pudiera ser.

Muchas gracias^^

Responder
German Porta 30/07/2012 - 22:04

Buenas, tengo un xml con esta estructura, como puedo hacer para que me lo reconozca, ya que no puedo cambiar la estructura del xml:

Digamos que no tiene la apertura y el cierre de los items.

Gracias

Responder
  Leer XML desde Android: SAX by victorpascual.es 07/08/2012 - 10:35

[…] los mejores artículos que tiene la web de sgoliver.net (web cojonuda por cierto sobre Android) es este artículo. Habla sobre el tratamiento de XML en Android utilizando SAX. Era tontería que os hiciera un nuevo […]

Responder
Canihojr 13/12/2012 - 17:39

Buenas! en el codigo de RssHandler en la linea 17 empiezas con «builder» y en el ejemplo descargado con sbTexto! me pegé 3 cuartos de horas buscando que fallaba hasta que me dio por bajarme el ejemplo!! jijiji

saludos y muchisisisismas gracias por tus tutoriales!!! para mi, los mejores de la red! :)

Responder
Lolo 28/12/2012 - 16:05

Bueno trabajo con este codigo, pero tengo un problema cada vez que ejecuto la aplicacion, se para y me sale el mensaje que la aplicacion a sido parada. No se porque ocurre esto, saludos y gracias, me ocurre en los tres metodos de parseo, unicamente pongo el codigo que viene aqui, ni mas ni menos, y lo intento ejecutar, ya que no lo muestra por pantalla pero me parece muy raro que se pare siempre.

Responder
carlos 15/04/2013 - 17:01

hola sgoliver
tengo una preguntilla como deberia hacer para tratar una etiquieta ![CDATA[ … ]]

Responder
WarioNeila86 26/04/2013 - 19:40

Hola,

Muy buen tutorial, todo bastante explicado.
A parte del error que ya han comentado más arriba del builder.append, todo muy bien.

He implementado estas clases (parecidas) para leer un XML de la carpeta assets, pero me añade espacios antes de los valores que tengo entre etiquetas en el XML.

Lo he solucionado así:
currentQuestion.setRightAnswer(sbText.toString().trim());

Pero no entiendo por qué se añaden esos 6 o 7 espacios antes de las cadenas de texto.

Un saludo.

Responder
miguel 03/05/2013 - 21:04

Hola como estas, verdaderamente esta super todo, hice este ejemplo y si corrió pero me arroja un txtview… Serà que me falte algo para ver el ejemplo completo SAludos…

Responder
estebusta 13/08/2013 - 3:45

Buenas noches estimado, me encantó el tutorial lo he leido mucho y ha funcionado a la perfeccion, pero tengo una pregunta, tal vez me puedes direccionar como hacerlo, si tengo estructuras con los mismos id, como leo todos, ya que lee el primer tag y salta el error porque dice q ya fue definido ese mismo.. o sea es algo asi

Algo
Algo2
Algo3

Por favor dame una mano o una idea.

Responder
Angel 17/09/2013 - 10:33

Hola Sgoliver, antes de nada felicidades por tu blog, estoy aprendiendo mucho gracias a tí. El tema que me ocupa es que estoy realizando un proyecto muy similar a tu lección: Tratamiento de XML en Android (I): SAX. La diferencia es que tengo un menu principal desde el que, mediante un boton, me voy a otra activity y es allí donde comienzo a realizar el ejemplo que tu haces. Es la única diferencia, un menu principal desde el que pulso un boton y me lleva a otra activity, en esta nueva activity tengo un boton para cargar un xml y mostrarla en el textview de debajo del boton. Pues no hay forma no me sale, supongo que el error se produce en que no utilizo la actividad principal para tratar el xml con sax pero no estoy seguro. Podrías ayudarme? gracias y saludos

Responder
Angel 17/09/2013 - 16:43

Ya esta resuelto, me faltaba un TextView!!!!!!!

Responder
Marcos 26/09/2013 - 16:40

Ante todo darte las gracias por el manual, es fantástico.

En segundo lugar quería comentarte una cosa del programa de este capítulo:

Resulta que he hecho una versión parecida pero con un XML adjuntado al programa, pués bien, el primer elemento a leer es un integer y al poner una instrucción tal como esta

xxxx.setIdpregunta(Ineger.parseInt(sbTexto.toString()));

me salía un error de parseInt.

Trás realizar varias pruebas indroduciendo un LOG me he dado cuenta que con una estructura como esta(en el XML a parsear)

1

2

el programa cuando encontraba el endElement devolvía el sbTexto 2 veces, una vacía y otra con el resultado correcto. Eso me producía un error en el parseInt con la respuesta vacia.

SOLUCION:

Al cambiar la linea sbTexto.setLength(0); que tú pones al final de endElement y colocarla en startElement el problema desaparece y funciona todo correctamente.

Gracias por todos.

Responder
Marcos 26/09/2013 - 16:44

Hola de nuevo, el ejemplo de XML a parsear no ha salido en el comentario anterior, es así:

ROW
IDPREGUNTAS 1 /IDPREGUNTAS
/ROW

Responder
Paco García 27/09/2013 - 8:17

Hola
Soy novato en esto pero creo que en el método:

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {

super.characters(ch, start, length);

if (this.notciaActual != null)
builder.append(ch, start, length);
}

donde pone builder debería poner sbTexto ¿no?

Un saludo

Responder
dani 09/10/2013 - 13:35

Muy útil. Muchas gracias

Responder
maer 21/10/2013 - 18:04

hola y muy buen post.

estoy desarrollando un proyecto similar a este… solo que tengo un problema al leer el contenido del xml me lo muestra tal y como esta en el; y al mostrarlo en el listview me muestra algunos links y etiquetal html como estas : .como puedo hacer para que esto no suceda…. es lo unico que me hace falta y no e encontrado la solucion a este problema.

de antemano muchas gracias por su atencion.

Responder
Desarrollando Android #4 Parseando un XML 15/11/2013 - 11:06

[…] Muchísimas gracias a Salvador Gómez por su tutorial en el parseo con SAX, que ha sido de mucha […]

Responder
arturo 17/01/2014 - 0:42

Muchas gracias por el tutorial :)

Responder
Patrick 03/03/2014 - 16:40

Hola. Tengo todo adaptado y me funciona bien, el problema es para cambiarlo con el AsynTask, que no se muy bien como es. ¿Podrías poner el código adaptado para AsynTask para que me vaya en versiones 3.0 y superiores por favor? Muchas gracias de antemano y buen trabajo

Responder
admin 03/03/2014 - 16:58

Hola Patrick, tienes el código fuente completo del ejemplo en GitHub para poder consultarlo online o descargarlo. Al final del artículo tienes el enlace directo al código.

Saludos.

Responder
Gabriela 28/05/2014 - 2:56

Hola Sgoliver, he realizado el ejemplo completo y también he visto el código. Me corre bien, pero hay un problema:

Solo funciona con el link que tu colocas.
He realizado una copia del contenido del xml que tu tienes y montado en otra dirección ip: http://www.nancysalcedodeiviz.com/xml/xml1.xml

Se la coloco a la app y no funciona, solo funciona con tu link.

Me podrias indicar que solución podria ser paa esto. Gracias y muchas Gracias por tremendo tutorial.

Responder
Pablo 08/07/2014 - 13:59

Hola al depurar este codigo me sale en el eclipse «source no found», he buscado en internet el problema y si bien veo que a muchos les ha pasado, yo no he podido solucionarlo. que puedo hacer?
Muchas Gracias.

Responder
Jesus 26/03/2015 - 9:33

Hola buenas, yo he utilizado tu código para comenzar una aplicación sobre mi blog. Me funciona todo correctamente pero no consigo mostrar correctamente la descripción del campo de mi xml. Contiene etiquetas html y se ven ¿como podría formatear el texto para que no me salgan estos tags?

Por otro lado, ¿podría poner cada campo en un textview distinto y aplicar estilos a cada uno?

Gracias por la ayuda!

Responder
Nino 28/05/2015 - 15:27

Excelente tutorial!!
que habría que hacer para sacar la información en master detail?

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