miércoles, abril 01, 2009

Manejando XML en AS3 de Forma Facil

A petición de un lector en Colombia, llamado Nestor, voy a enseñarles como hacer un lector de RSS, lo voy a dividir en 2 partes, empezando con esta, que es leer XML con AS3.


En esta parte veremos de forma rápida que es XML, como cargarlo y la forma de navegar en él con el standard E4X.


Un XML para los que no saben, es un archivo de texto plano, como uno generado por notepad, con una estructura similar a los nodos de HTML, la diferencia se basa, en que XML se utilizará para enviar datos, y que su estructura puede ser la que nosotros necesitemos, por ejemplo:


Si tenemos una tabla con nombres y apellidos se vería así:


Tabla Personas

Nombre Apellido


Juan Perez

Daniel Rodriguez


La idea de XML es llevar estos datos a través de una estructura predefinida de texto, y que muchos lenguajes de programación puedan leerlo sin crear un nuevo protocolo, así, nosotros sabemos que los campos que debemos crear, son, nombre y apellido, y su contenido, juan perez, y daniel rodrigez en la tabla llamada personas.


para definir un campo en XML se abre etiquetas como en HTML, y se pone el nombre que uno necesite, así, si mi tabla se llama personas, hago lo siguiente


<tabla nombre="personas">

..

</tabla>


definimos una estructura simétrica un nodo tabla se cierra con /tabla, y su contenido iría donde estan los dos puntos seguidos.


Ahora, seria mas sencillo si pudiéramos manejar a cada nombre y apellido como uno solo (persona) así que creamos un nodo para manejar a ambos:


<tabla nombre="personas">

<persona nombre="" apellido="">

</tabla>




Observen que el nodo persona tiene al final "/>" ya que no tiene más nodos dentro de si, asi que es innecesario tener el complemento si no hay contenido, simplemente lo cerramos (/) en el mismo nodo.


Ahora, nosotros tenemos 2 personas, que hacemos? bueno, hacemos una copia del mismo nodo "persona" vacío, y llenamos los datos:


<tabla nombre="personas">

<persona nombre="Juan" apellido="Perez">

<persona nombre="Daniel" apellido="Rodriguez">

</tabla>






Ahora tenemos una tabla de nombre personas, con dos personas dentro, cada uno con sus atributos de nombre y apellido, si quisiéramos otra tabla, dentro de nuestro archivo xml, puede llevar la misma estructura, pero para diferenciarla, podemos poner de nombre en la tabla "recursos humanos" por ejemplo, para diferenciarlos.


Muy bien, ya que sabemos que es un XML, podemos leerlo desde el flash, copiemos entonces nuestro XML recién creado en un archivo .txt, pueden abrir el notepad, o cualquier editor de texto disponible (yo uso <a href="www.flashdevelop.org">flash develop</a>) y lo guardamos con el nombre "personas.txt" o "personas.xml", tomen en cuenta que la extensión no influye en el contenido del archivo al ser leído por flash, solo es una identificación para el sistema operativo sobre como y con que programa debería interpretarlo, si le ponen .xml, pueden abrirlo nuevamente con notepad o cualquier editor de texto.


Listo el archivo, lo guardamos en un directorio conocido, y creamos un .fla en el mismo directorio donde guardamos el .xml; luego, creamos una layer de actions, y pegamos el siguiente código:


var url:String = "personas.xml";

var urlRequest:URLRequest = new URLRequest(url);

var urlLoader = new URLLoader(urlRequest);


var xml:XML;


urlLoader.addEventListener(<div id=":8e" class="ii gt"><wbr>Event.COMPLETE, onCompleteEvent )


function onCompleteEvent(e:Event){

xml = new XML(e.target.data)

trace(xml)

}


Para los que vienen de AS2, esto es complicado, por que cuando uno inicia, piensa que se tiene que reaprender un monton de funciones para hacer lo que antes hacias en un par de lineas, bueno esto no es cierto, generalmente, aunque el codigo parezca largo, se repite en otras operaciones, y despues con el uso, se encuentra la utilidad del manejo separado de eventos.


<span style="font-weight: bold;">Explicando el codigo</span>: Bueno en la primera linea nada dificil, definimos la ruta de donde se encuentra nuestro XML, como está junto al fla, es solo "personas.xml", si estuviera en la unidad C, seria asi: "c:/personas.xml", o dentro de otras carpetas si asi se necesita; luego tenemos este URLRequest, que es el objeto que armamos para solicitar datos por medio de la siguiente objeto, URLLoader, tambien hay otro objeto por el que podemos solicitar datos con URLRequest, y es el Loader, como por ejemplo, para cargar imagenes dinamicamente, en lugar de XML. Luego el URLLoader nos hará la llamada a "personas.xml", y nos dará informacion que necesitamos, como un objeto de tipo XML de flash con la extructura del archivo XML, tamaño, y algo muy importante, avisarnos cuando se cargó el archivo, ya que no podemos empezar a usarlo hasta que esté completamente cargado, entonces, cuando llamamos al metodo addEventListener de URLLoader, le pedimos que nos avise del evento COMPLETE, y que llame a una funcion que tendrá el codigo para trabajar el XML como si ya se hubiera cargado, la funcion, onCompleteEvent, se programa de esta forma, se debe pensar que para el momento en que se llame, debe estar cargado ya. Como paramentro de nuestra function onCompleteEvent, tenemos de nuevo un EVENT, para los que no comprenden los eventos, se preguntarán, de donde sale este e:Event, realmente la estructura de la function del evento no la definimos nosotros, está definida por flash, como paramentro de addEventListener se necesita que se envíe una function con ese parametro, para que? para que usted pueda usarlo, es un parametro generico; por ejemplo, usted no solamente puede tener un XML para cargar, sino varios, al mismo tiempo, o uno despues del otro, pero resulta que necesita que en COMPLETE se les haga el mismo procedimiento, asi que en lugar de definir 2 onCompleteEvent, ud solo define uno, pero ud no puede saber cuando le llega, ni cual le llega, asi que se le envia este parametro "e" con toda la informacion, dentro viene, el XML que se llamó por medio del URLLoader, pero hay que sacarlo, asi llamamos a e.target que representaria al URLLoader que disparó o produjo el evento COMPLETE, y si nos fijamos en la ayuda de Adobe, para URLLoader, el atributo "data", contiene informacion cargada sin formato, por lo que tenemos que darle forma con un objeto que nos ayude a manipularlo, como nosotros sabemos que es XML, usamos el objeto XML de flash, y lo guardamos, hacemos un trace(xml) y vemos la salida en la consola, si es el contenido de nuestro personas.xml que habiamos creado antes.


Usando XML: Bueno ya que tenemos el objeto, podemos sacar nuestra informacion, para el standard de E4X, resulta que podemos llamar a los nodos con notacion de "puntos", de la misma forma en que llamamos a una propiedad de un objeto en flash, por ejemplo, si un MovieClip llamado my_mc tiene una propiedad x, la llamamos asi: my_mc.x, y sabemos su coordenada x en el plano cartesiano de flash; igual podemos con el objeto XML de flash.


Si vemos nuestro XML tiene dos formas de obtener datos, una podemos sacar a la persona, y la otra sacar el nombre o apellido directamente, para esto el standard nos dice, que un nodo se saca simplemente llamandolo por el nombre:


trace(xml.persona)


Si hacemos esto, nos imprime en el panel de salida, los nodos XML de todas las personas, en teoria, eso es lo que buscamos, pero como "persona" no es un nodo UNICO, nos dará todos. Pero esto tampoco nos sirve, aunque no se note uno esperaria que xml.persona fuera un array y lo pudieramos por indices, por ejemp xml.persona[0] para obtener a la primera persona, pero no funciona, pueden intentarlo.


En cambio, existe una notacion especial para obtener un XMLList, que si podemos manejar como lista:


trace(xml..persona)


Si bien imprime lo mismo, este si podemos usarlo como un Array de flash, y asi podemos imprimir cada atributo (nombre, apellido) de cada nodo.


Ahora, para sacar los atributos de cada nodo, existe otra notacion especial, muy simple, sin llamadas a funciones incomodas como en as2, para llamar a un atributo usamos esto:


xml..persona[0].@apellido


Pero que sucede si tenemos un XML en que cada día cambia el tamaño del numero de personas? Podemos hacer esto:

<code>

function onCompleteEvent(e:Event){

xml = new XML(e.target.data)

var numPersonas = xml..persona.length();

for(var k=0;k<;numPersonas;k++){

trace(xml..persona[k].@apellido)

}

}

</code>


y asi automatizar cada nodo, y sacar la info que realmente necesitamos.


<tabla>

<persona>

<nombre>juan</nombre>

<apellido>perez</apellido>

</persona>

</tabla>


Este XML podemos llamarlo con una notación diferente, ya que no tiene atributos, sino solo nodos:


xml..persona[0].nombre


igual con el apellido.


Para un feed necesitaríamos cargar el XML de la misma forma, pero la diferencia esta en el parseo ( lectura desde el código y manipulación ).


Por lo que eso lo trataremos en la siguiente oportuniad.


Espero haya sido de utilidad


8 comentarios:

aquiles dijo...

Mae tengo un compa que ocupa ayuda con Webservices en AS3 por que no se pone un tutorial a ver si lo ayuda? jajaja

Absulit dijo...

yo conozco a ese compa suyo, ya le ayudé con ese problema ;-)

Anónimo dijo...

Excelente Aporte. Tal vez es mejor usar foreach en lugar del for al recorrer las personas..

Saludos
Patricio

Anónimo dijo...

la informaciГіn muy buena http://nuevascarreras.com/category/cialis-generico/ cialis 20 Rimosso [url=http://nuevascarreras.com/cialis/ ]cialis dosis diaria [/url]

Anónimo dijo...

El pensamiento justo [url=http://csalamanca.com/comprar-viagra-generico/ ]la viagra y sus efectos [/url] la pregunta muy entretenida http://csalamanca.com/comprar-viagra-generico/ la viagra en la mujer

Anónimo dijo...

Hola,

estoy utilizando AS3, solo quiero q mi flash llame un xml, pero son nombres q caen 3 lugares diferentes, es una base de datos con nombres pero se visalizaran 3 a la vez, como le puedo hacer si en tu ejemplo solo lo pones para uno, tendria que hacer 3 Loader con diferente nombre? o el mismo?

Saludos por cierto muy bueno tu blook

Absulit dijo...

Hola, lo que puedes hacer es lo siguiente, si tenes todos los paths los xml en un array, lo vas recorriendo de uno en uno, cargas el primero, y en el Event.COMPLETE del XML avanzas en el array y cargas el siguiente, asi hata que se te acaben los elementos del array.
Si quieres cargar todas al mismo tiempo y el numero de urls o paths es el mismo, haces un loader por cada uno; luego cuando termines con cada loader, eliminas los eventos asociados y le pones null al loader .
Espero te sirva la respuesta.

Saludos y gracias por visitar el blog

cosisikh dijo...

Super-Duper site! I am loving it!! Will come back again – taking your RSS feeds also, Thanks.

cheap nolvadex