Lector de RSS usando XPath

Volviendo al post de hace unos días sobre XPath. Alberto Bueno comentó sobre lo bueno de poner un ejemplo que ilustrase lo comentado. Ayer me puse manos a la obra y con ánimos de esclarecer un poco más las virtudes de usar XPath en vuestros proyectos, surgió el siguiente ejemplo.

Para ello he creado una pequeña clase que emula un lector de RSS. He intentado hacerla lo más sencilla posible para que sea fácil de probar. La clase es la siguiente:

import com.xfactorstudio.xml.xpath.*;

/*
* @class com.carlosrovira.rss.RSSReader
* @author Carlos Rovira
* @version 0.4
* @description Ejemplo simple de lector RSS usando las clases para XPath de Neeld Tanksley (xfactorstudio)
* @usage En el primer frame poner las siguientes dos lineas
*			import com.carlosrovira.rss.RSSReader;
*			var r:RSSReader = new RSSReader(this);
* @param   _target_ (MovieClip) MovieClip donde se creará el lector de RSS
*/
class com.carlosrovira.rss.RSSReader
{
        private var myDoc:XPathDocument;		// --- Objeto XPath
        private var rssURL:String = "http://www.carlosrovira.com/b2rss.php"; // --- Fichero que proporciona las noticias
        private var rssCount:Number;			// --- Numero de noticias
        private var rssCounter:Number = -1;		// --- Contador de noticias
        private var target:MovieClip;			// --- MovieClip donde colocaremos las noticias
        private var rss_txt:TextField;		// --- TextField donde escribiremos las noticias
        private var rss_fmt:TextFormat;		// --- Formato del TextField.
        private var delay:Number = 3000;		// --- Tiempo en milisegundos que tarda en aparecer una nueva noticia. 3sg por defecto
        
        function RSSReader(_target_:MovieClip)
        {
                System.useCodepage = true // --- Eliminar esta linea si usais un fichero codificado en unicode
                target = _target_;
                createUI(target);
                
                // --- Inicialización del Objeto XPath
                myDoc = new XPathDocument();
                myDoc["owner"] = this;
                myDoc.onLoad = function(success)
                {
                        if (success)
                        {
                                // --- Recogemos el numero de noticias en el RSS mirando la longitud del Array de items
                                this["owner"].rssCount = XPath.selectNodes(this, "//item").length;
                                // --- Ejecutamos la función de muestra de las noticias con un "delay" en milisegundos
                                setInterval(this["owner"].showNewsItem , this["owner"].delay, this["owner"]);
                        }
                        else
                        this["owner"].target.rss_txt.htmlText = "Error al cargar el RSS...";
                }
                myDoc.load(rssURL);
        }
        
        function createUI(target:MovieClip):Void
        {
                // --- TextFormat para asignar al TextField
                rss_fmt = new TextFormat();
                rss_fmt.size = 12;
                rss_fmt.color = 0x0052A4;
                rss_fmt.font = "Trebuchet MS";
                
                // --- TextField donde visualizaremos las noticias
                target.createTextField("rss_txt", 0, 0, 0, 200, 150);
                target.rss_txt.multiline = true;
                target.rss_txt.wordWrap = true;
                target.rss_txt.background = true;
                target.rss_txt.backgroundColor = 0xE7EEF4;
                target.rss_txt.html = true;
                target.rss_txt.htmlText = "Cargando noticias...";
                target.rss_txt.setTextFormat(rss_fmt);
        }
        
        function showNewsItem(rss:Object):Void
        {
                // --- Realizamos la busqueda: el primer parametro es el XML, el segundo es la querystring
                // --- En title, description y link obtendremos tres arrays con el texto de los nodos.
                var title = XPath.selectNodes(rss.myDoc, "//item/title/text()");
                var description  = XPath.selectNodes(rss.myDoc, "//item/description/text()");
                var link  = XPath.selectNodes(rss.myDoc, "//item/link/text()");
                
                // --- Aunmentamos el contador hasta llegar al número de noticias existente, entonces lo ponemos a cero
                (rss.rssCounter == rss.rssCount-1)? rss.rssCounter = 0 : rss.rssCounter++;
                
                // --- Muestra en el campo de texto la noticia correspondiente
                rss.target.rss_txt.htmlText = "<b><u><a href='"
                + link[rss.rssCounter] + "'>"
                + title[rss.rssCounter] + "</a></u></b><br />"
                + description[rss.rssCounter].substr(0, 150) + " [...]";
                // --- Formateamos el texto
                rss.target.rss_txt.setTextFormat(rss.rss_fmt);
        }
}

Me gustaría comentaros algunas peculiaridades de XPath.

Como veis la típica querystring que he utilizado es algo del estilo a “//item/title/text()”. Al comenzar con // estoy seleccionando todos los nodos incluso en diferentes niveles del árbol XML. En cambio si empiezo con / estoy indicando un camino absoluto al nodo.

Al utilizar text() estoy seleccionando el texto dentro del nodo. De esta manera devuelvo un Array con todos los textos de los nodos que cumplen el criterio seleccionado (es decir, [valor,valor]). Si recorto la querystring hasta “title”, el Array estaría formado por elementos title (es decir [<title>valor</title>,<title>valor</title>]). Y de esta manera habría que usar title[i].firstChild.nodeValue en cada elemento para llegar al texto.

Por último funciones como count, substring o contains no devuelven valores, solo son usadas para seleccionar nodos y funcionan solo dentro de predicados (osea dentro de []). Por ejemplo:

trace(XPath.selectNodes(this, "//item[contains(title, 'Flash')]/title/text()"));

Selecciona los titulos de los items que contengan \’Flash\’, esto es devuelve un Array con dichos titulos.

Nota: Como se comenta en la clase, la manera de utilizar esta clase es colocar en un documento nuevo y en el primer fotograma las siguientes dos lineas:

import com.carlosrovira.rss.RSSReader;
var r:RSSReader = new RSSReader(this);

10 Comentarios

  1. Buffff… Esto si que me va a ir bien XD

    Tengo que leer un monton de XMLs en mi trabajo y esto me viene de perlas, es mucho más fácil trabajar con estas referencias al XML.

    La verdad es que estaba harto del firstChild.childNodes, jajaja.

    Por último, decir que soy nuevo por aqui, pero lo voy a visitar mas a menudo. Hay pocos blogs buenos como este…

    Y ya que estoy aqui una preguntita, jeje. Tengo mi pagina hecha con OOP en AS1, pero no consigo pasarla a AS2, algun sitio donde pueda mirarme bien las clases en AS2? Pero que este en castellano, que me da palo traducir al ingles, jajaja.

    Un saludo…

  2. Hola Raúl ;),
    Pues por ejemplo, los chicos de Design-nation (Cásar y Javier), suelen usar bastante AS2.
    Tamián ahora Toni Lopez de After-Hours está metiendose de lleno en el tema.

    Me alegro que te animes a usar AS2, aunque no tengo nada en contra del AS1, pues tambián he disfrutado lo mio usando clases prototipadas.

    saludos y bienvenido! 🙂

  3. Bueno, pues ya me lo he empezado a mirar y la verdad es que no esta nada mal.

    Ahora mismo tambián estoy haciendo tutoriales sencillitos, para los que empiezan con OOP AS2.0, y os aseguro que son sencillitos porque yo no se, y es lo que voy haciendo, de momento van 2, cuando tenga cuatro o cinco los subire a mi page, y a ver que tal le va a la gente…

    La gente de design-nation se lo curran bastante pero para los muy iniciados a lo mejor es muy duro, sus ejemplos son buenisimos, pero quiza muy dificiles para novatos.

    En fin… siempre hay que practicar para aprender, asi que seguiremos en ello

  4. Eso está bien, cuanto más información, la gente le perderá el miedo 🙂
    Yo te aconsejo que incluso subas ya los tutos que tengas…así­ la gente podrá ir digiriendolos poco a poco 🙂

    saludos!

  5. Bueno, pues ya está. He subido tres tutoriales bastante sencillitos sobre clases en AS 2.0.

    Espero que a la gente les vaya bien… Los encontrareis en la sección Tutoriales.

    Un saludo 😉

  6. Hola ,exelente tu idea,

    osea podrias cargar el contenido de un blog en una pagina flash? o por lo menos los titulares?
    perdona estoy aprendiendo en los sitios dinamicos, y me gustaria poder hacer , que los titulares de mi blog en wordpress aparecsan en mi sitio flash. gracias por tu ayuda
    estoy en un nivel intermedio en php y flash(mas bien debutante je je)

    saludos

    Cri5tian

  7. Recuerda que debes usar las clases de xfactor (mira el primer import de la primera linea). El mensaje de error se debe a que no tienes esas clases en el classpath.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *