De XML a Flash

2º parte del artículos sobre Bases de datos y XML para Flash utilizando ASP.
Presentación del archivo XML y algunas nociones sobre Arrays

En la primera parte de este articulo (Parte 1 - de Access a XML) desarrollamos una página ASP que, luego de conectarse a una base de datos Access, recogía los datos correspondientes a los representantes comerciales de una empresa ficticia y los volvía a grabar en formato XML respetando la estructura jerárquica original.
Esta jerarquía implicaba que los Representantes estaban divididos según su País de residencia y que a su vez los Países estaban agrupados en Areas Geográficas.
Independientemente de su origen (generado a partir de una base de datos o tipeado directamente en un editor de texto) el archivo XML resultante tiene la estructura que se muestra en la siguiente imagen:


Nota: no se muestran los datos, solo la arquitectura general del archivo para el utópico caso de un Area con un solo País y dos Representantes.

Desarrollaremos el resto del trabajo dentro del Flash, desde donde cargaremos el contenido del archivo XML en una serie de Arrays (o Matrices) que a su vez utilizaremos para mostrar dinámicamente los datos.
En este contexto, dinámicamente significa que crearemos en tiempo de ejecución los movieclips que contendrán el texto que queremos mostrar.

Para tratar de que la cosa sea un poco más clara comentaremos primero cuáles serán los Arrays que utilizaremos:

  • Un Array de Areas Geográficas, cuyos elementos serán las Areas que se encuentren en el XML. En el caso del ejemplo será: areas = ["América del Sur", "América Central y Caribe", "América del Norte", "Europa"]
  • Un Array por cada Area Geográfica, cuyos elementos serán los Países que están incluídos en esa Area. Por ejemplo: América del Sur = ["Argentina", "Brasil", "Chile", "Uruguay"]
  • Un Array por cada País, cuyos elementos serán los datos de cada uno de los Reresentantes de ese País. Este Array es peculiar ya que sus elementos son en realidad Arrays Asociativos, que guardan pares dato:"valor", y son especialmente útiles para los datos personales de los Representantes. Veamos el ejemplo simplificado del Array Argentina: Argentina = ["elem1", "elem2"] tiene dos asociativos: elem1 = {ciudad:"Buenos Aires",nombre:"Alejandro",apellido:"González",…etc.} elem2 = {ciudad:"Córdoba",nombre:"Mabel",apellido:"Lucero",…etc.} Para acceder a sus valores: Argentina [0].nombre = Alejandro Argentina[1].ciudad = Córdoba
Trabajando en Flash con ActionScript

Ya con el Flash, abrimos una nueva película que denominaremos representantes.fla.
Denominaremos la primera capa como 'actionscript' y allí colocaremos todo el código utilizando el Panel de Acciones (F9 para abrir).
En el fotograma 1 colocaremos primero el código encargado de:

  • Cargar los datos del XML dentro de un Objeto XML del Flash
  • Construir el esquema de Arrays que analizamos un poco más arriba

Utilizaremos tres bucles for anidados (Areas, Países de cada Area y Representantes de cada País). Debemos recordar que desconocemos de antemano el nombre que tomarán la mayoría de los Arrays (dependerán de los datos contenidos en el XML), por lo que deberán declararse como _root[nombre_variable] (sin punto).

Cargar datos y armar Arrays

// Nos aseguramos que se muestren bien los acentos

System.useCodepage = true;
// Creamos el objeto que guardará los datos del archivo XML
represXML = new XML();
represXML.ignoreWhite = true;
//Cargamos el archivo XML en el objeto recién creado
represXML.load("../xml/representantes.xml");
// Cuando termina de cargar lo mandamos a organizar para poder mostrar los datos
represXML.onLoad = organizarXML;
stop();
// Esta es la función encargada de armar los Arrays a partir de los datos
function organizarXML() {
// Array para las Areas Geográficas
areas = new Array();
// Primer bucle para buscar Areas revisando todos los primeros nodos
// ejemplo: América del Sur, América Central, etc.
for (yy=0; yy<represXML.firstChild.childNodes.length; yy++) {
// Agregar el nombre del Area (guardado como Atributo) al Array de Areas Geográficas
areas.push(represXML.firstChild.childNodes[yy].attributes.nombre);
// Crear un Array con el nombre de cada una de las Áreas encontradas
_root[represXML.firstChild.childNodes[yy].attributes.nombre] = new Array();
// Segundo bucle para buscar el nombre de los Países (atributo) de cada Area
// ejemplo: Argentina, Brasil, etc.
for (aa=0; aa<represXML.firstChild.childNodes[yy].childNodes.length; aa++) {
// Agregar el nombre del País al Array del Area a la que pertenece
_root[represXML.firstChild.childNodes[yy].attributes.nombre].push( represXML.firstChild.childNodes[yy].childNodes[aa].attributes.nombre);
// Utilizar el nombre de cada País (ejemplo: Argentina) para crear un nuevo Array
// donde se van a guardar los datos de los Representantes que pertenecen a ese país
_root[represXML.firstChild.childNodes[yy].childNodes[aa].attributes.nombre] = new Array();
// Tercer bucle para entrar a cada Representante y leer sus atributos
for (bb=0; bb<represXML.firstChild.childNodes[yy].childNodes[aa].childNodes.length; bb++) {
// Crear un Objeto para guardar los datos de cada Representante como si fueran propiedades del Objeto (array asociativo con pares dato:"valor" )
repre = new Object();
repre.ciudad = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.ciudad;
repre.nombre = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.nombre;
repre.apellido = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.apellido;
repre.telefono = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.telefono;
repre.email = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.email;
// Agrego el Objeto (datos representante) al Array del país
_root[represXML.firstChild.childNodes[yy].childNodes[aa].attributes.nombre].push(repre);
// Elimino el Objeto
delete repre;
}
}
}
// Mandamos los datos ya organizados a que se muestren (la función está más abajo)
mostrarDatos();
}


En este punto tenemos nuestros datos poblando una serie de Arrays y solo nos resta mostrarlos ordenadamente.


Mostrar los datos dinámicamente

Dado que disponemos de tres tipos de datos: Area, País y los datos del Representante, agregaremos a la Biblioteca tres movieclips. Cada movieclip tendrá como contenido cajas de texto dinámico que mostrarán el contenido de las siguientes variables:

  • mc_areas (identificador para linkage: mc_areas): tx_area
  • mc_paises (identificador para linkage: mc_paises): tx_pais
  • mc_repres (identificador para linkage: mc_repres): tx_ciudad, tx_nom_ape, tx_telefono y tx_email

Por ejemplo, para el mc_areas:


Como estos movieclips se agregarán al escenario dinámicamente debemos indicarle al Flash que los exporte para ser utilizados en tiempo de ejecución. Esto lo realizamos indicando un identificador para Linkage, que por comodidad establecemos igual al nombre del movieclip.
Para establecer el identificador se debe pulsar con el botón derecho del mouse sobre el movieclip en la Biblioteca y seleccionar Linkage … en el menú emergente.

Básicamente lo que haremos será crear un movieclip vacío que denominaremos "contenedor", que contendrá la lista en sí, utilizando createEmptyMovieClip(nombre de instancia, nivel).
De un modo similar a lo que hicimos antes, utilizaremos tres bucles for anidados para recorrer nuestros Arrays e iremos sucesivamente agregando a "contenedor" instancias de los movieclips que tenemos en la Biblioteca mediante attachMovie(id. de linkage, nombre de instancia, nivel).

Como la lista resultará extensa (tendrá un desarrollo vertical mayor que el alto de la película) crearemos otro movieclip vacío (denominado "mc_msk") y dentro dibujaremos con ActionScript un rectángulo del tamaño apropiado para oficiar de "ventana". Colocando a "mc_msk" como máscara de "contenedor" lograremos ocultar el sobrante de la lista y solo restará hacer que "contenedor" se deslice hacia arriba y hacia abajo dentro de ciertos límites para que todos los Representantes resultes visibles.

El siguiente código continúa al anterior:

function mostrarDatos() {
// Creamos un mc vacío para encapsular la lista de Representantes
// y lo posicionamos en el escenario principal
_root.createEmptyMovieClip("contenedor", 300);
_root.contenedor._x = 10;
_root.contenedor._y = 50;
// Construímos la lista
intContaPaises = 0;
intContaRepres = 0;
intPosicion = 0;
intSeparar = 50;
// Para cada una de las Areas
for (aa=0; aa<areas.length; aa++) {
_root.contenedor.attachMovie("mc_areas", "mc_areas"+aa, aa);
_root.contenedor["mc_areas"+aa]._y = (intPosicion * intSeparar);
_root.contenedor["mc_areas"+aa]._x = 25;
_root.contenedor["mc_areas"+aa].tx_area = areas[aa];
intPosicion++;
// Para cada uno de los Países del Area
for (bb=0; bb<_root[areas[aa]].length; bb++) {
_root.contenedor.attachMovie("mc_paises", "mc_paises"+intContaPaises, 100+intContaPaises);
_root.contenedor["mc_paises"+intContaPaises]._y = (intPosicion * intSeparar);
_root.contenedor["mc_paises"+intContaPaises]._x = 45;
_root.contenedor["mc_paises"+intContaPaises].tx_pais = _root[areas[aa]][bb];
intPosicion++;
// Para cada Representante de cada País
for (cc=0; cc<_root[_root[areas[aa]][bb]].length; cc++) {
_root.contenedor.attachMovie("mc_repres", "mc_repres"+intContaRepres, 200+intContaRepres);
_root.contenedor["mc_repres"+intContaRepres]._y =(intPosicion * intSeparar);
_root.contenedor["mc_repres"+intContaRepres]._x = 55;
_root.contenedor["mc_repres"+intContaRepres].tx_ciudad = _root[_root[areas[aa]][bb]][cc].ciudad;
_root.contenedor["mc_repres"+intContaRepres].tx_nom_ape = _root[_root[areas[aa]][bb]][cc].nombre + " " + _root[_root[areas[aa]][bb]][cc].apellido;
_root.contenedor["mc_repres"+intContaRepres].tx_telefono = _root[_root[areas[aa]][bb]][cc].telefono;
_root.contenedor["mc_repres"+intContaRepres].tx_email = _root[_root[areas[aa]][bb]][cc].email;
intPosicion++;
intContaRepres++;
}
intContaPaises++;
}
}
// Creamos un nuevo mc en el que dibujamos un rectángulo con las dimensiones
// apropiadas para el tamaño de nuestra película
_root.createEmptyMovieClip("mc_msk", 301);
mc_msk._x = 10;
mc_msk._y = 50;
// Dibujamos el rectángulo (en este caso de 530px de ancho por 350px de alto)
// No importan los colores de trazo y relleno porque no se verá, lo utilizaremos como máscara.
with (mc_msk) {
beginFill(0xff0000,50);
lineStyle(1,0x00ff00,100);
lineTo(530,0);
lineTo(530,350);
lineTo(0,350);
lineTo(0,0);
endFill();
}
// Enmascaramos el listado con el recuadro que acabamos de dibujar y LISTO! ;-)
_root.contenedor.setMask(mc_msk);
}
Como último detalle ponemos el código de los botones que manejan el scroll de "contenedor":
Botón Subir:
on (release) {
if (_root.contenedor._y < _root.mc_msk._y) {
_root.contenedor._y += _root.intSeparar;
}
}
Botón Bajar:
on (release) {
if (_root.contenedor._y > _root.mc_msk._height - _root.contenedor._height) {
_root.contenedor._y -= _root.intSeparar;
}
}


Al ejecutar la película terminada se obtendrá un resultado similar al de la siguiente imagen, dependiendo de los detalles accesorios de presentación que se agreguen:

Autor

Fernando Campaña

Programación - Multimedia

Compartir

Comentarios

nicolacho

09/10/2007
puedes compartir conmigo el fla. he tratado de hacer el tutorial y ya me estoy frustrando.

Saludos

Manuel

23/3/2010
explicacion
me parece bueno lo de los arrays para el uso de los xml, aunq me gustaria saber cual seria el procedimiento de mostrar los datos en los arrays directamente en cajas de texto en mi pelicula inicial sin tener que llamarlos, y como se podria manejar los datos por medio de botones en lugar de cargar todos en una pagina que muestre varias
Gracias por la ayuda

raul

10/3/2014
y las fotos???
Hola, todo esta muy bien, pero me gustaria que se incluyeran fotos de los respresentantes, como se podria manejar fotos con este array???