Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
Mysteriis

Importar Xml para o flash

Recommended Posts

Mysteriis

Boas,

estou a tentar importar um Xml com a seguinte estrutura

<site>

<links>

  <categoria nome="Exemplo"/>

  <subcategoria nome="Exemplo"/>

  <subcategoria nome="Exemplo"/>

  <subcategoria nome="Exemplo"/>

</links>

<links>

  <categoria nome="Exemplo"/>

<subcategoria nome="Exemplo"/>

</links>

</site>

Gostaria de criar dinamicamente movieclips que importassem lá para dentro a categoria e as suas subcategorias.

Cumprimentos

Mysteriis

Share this post


Link to post
Share on other sites
coxosclassic

boas,

Podes usar recursividade na procura do teu XML.

Após teres carregado o xml, será algo género:

var mc:MovieClip;
var mcContainer:MovieClip = new MovieClip();

XMLrecursion(data); //sendo data, o teu XML...

function XMLrecursion(d:XML):void
{
var i:int = 0;
for( i = 0; i < d.children().length(); i++) XMLrecursion( d.children()[i] );

//chegamos ao fim do "nó" de XML...
if( i == 0 ) 
{
	//constroi MovieClip
	mc = new MovieClip();

	// define propriedades
	mc.type = new String();
	mc.type = d.name();
	mc.nome = new String();
	mc.nome = d.@nome;

	trace( mc.type ) // devolve o nome do nó (categoria ou subcategoria)
	trace( mc.nome ) // devolve o conteudo do atributo "nome" (Exemplo)
	trace("--------------");

	// adiciona ao contentor
	mcContainer.addChild(mc);
}
}

trace( mcContainer.numChildren ) //devolve o numero de mc's (6 no teu caso)

espero que ajude,

CC


Cumps,

cc

Share this post


Link to post
Share on other sites
Mysteriis

Sou ainda iniciado nestas andanças. Não tou a conseguir importar os dados. Vou o postar o meu codigo para ver o que estou a fazer mal.


var url:URLRequest=new URLRequest("menu.xml");
var infoXML:URLLoader = new URLLoader();
infoXML.load(url);

var MeuXML:XML = new XML();
MeuXML.ignoreWhite = true;

var mc:MovieClip;
var mcContainer:MovieClip = new MovieClip();

XMLrecursion(MeuXML);//sendo data, o teu XML...

function XMLrecursion(d:XML):void {
var i:int=0;
for (i = 0; i < d.children().length(); i++) {
	XMLrecursion( d.children()[i] );
}

//chegamos ao fim do "nó" de XML...
if (i==0) {
	//constroi MovieClip
	mc = new MovieClip();

	// define propriedades
	mc.type = new String();
	mc.type=d.name();
	mc.nome = new String();
	mc.nome=d.@nome;

	trace( mc.type );// devolve o nome do nó (categoria ou subcategoria)
	trace( mc.nome );// devolve o conteudo do atributo "nome" (Exemplo)
	trace("--------------");

	// adiciona ao contentor
	mcContainer.addChild(mc);
}
}

trace( mcContainer.numChildren );//devolve o numero de mc's (6 no teu caso)

Cumprimentos

Share this post


Link to post
Share on other sites
coxosclassic

tens tudo certo, mas tens de esperar que o infoXML carregue o ficheiro:

var url:URLRequest=new URLRequest("menu.xml");
var infoXML:URLLoader = new URLLoader();
infoXML.addEventListener(Event.COMPLETE, infoLoaded);
infoXML.load(url);

function infoLoaded( e:Event ):void
{
   var MeuXML:XML = new XML(e.target.data);
   
   XMLrecursion(MeuXML);
}

var mc:MovieClip;
var mcContainer:MovieClip = new MovieClip();


function XMLrecursion(d:XML):void {
        var i:int=0;
        for (i = 0; i < d.children().length(); i++) {
                XMLrecursion( d.children()[i] );
        }

        //chegamos ao fim do "nó" de XML...
        if (i==0) {
                //constroi MovieClip
                mc = new MovieClip();

                // define propriedades
                mc.type = new String();
                mc.type=d.name();
                mc.nome = new String();
                mc.nome=d.@nome;

                trace( mc.type );// devolve o nome do nó (categoria ou subcategoria)
                trace( mc.nome );// devolve o conteudo do atributo "nome" (Exemplo)
                trace("--------------");

                // adiciona ao contentor
                mcContainer.addChild(mc);
        }
}

trace( mcContainer.numChildren );//devolve o numero de mc's (6 no teu caso)

cumps,

CC


Cumps,

cc

Share this post


Link to post
Share on other sites
Mysteriis

CC não quero abusar da tua boa vontade, pois tens sido impecável e todas as tuas dicas têm sido excelentes para resolver a minha questão.

Quando colocei a minha dúvida não fui bastante explícito, pois o que pertendia era que a informação de cada nó "links" ficasse dentro de um movieclip, e quando chegasse ao fim desse "nó" importava esse movieclip para o stage e passava para outro nó. Assim ficavam no mesmo movieclip a categoria e as suas subcategorias.

var url:URLRequest=new URLRequest("menu.xml");
var infoXML:URLLoader = new URLLoader();
infoXML.addEventListener(Event.COMPLETE, infoLoaded);
infoXML.load(url);

function infoLoaded( e:Event ):void {
var MeuXML:XML=new XML(e.target.data);

XMLrecursion(MeuXML);
}

var mc:Mc;
//var mcContainer:McContainer = new McContainer();

function XMLrecursion(d:XML):void {
var i:int=0;
for (i = 0; i < d.children().length(); i++) {
	XMLrecursion( d.children()[i] );
	mc.x=200;
	mc.y=190+i*30;
}
//chegamos ao fim do "nó" de XML...
if (i==0) {
	mc = new Mc();
	mc.type = new String();
	mc.type=d.name();
	mc.nome = new String();
	mc.nome=d.@nome;
	mc.texto.text=mc.nome;
	addChild(mc);
}
}

 

O mc agora é um movieclip que esta na libraria e lá dentro tem um campo de texto dinâmica com o Instance name texto.

Cumprimentos

Mysteriis

Share this post


Link to post
Share on other sites
coxosclassic

boas,

pensava que querias criar vários mc's de acordo com as categorias e subcategorias...  :)

nesse caso, o uso de recursão seria a melhor forma de o conseguires, mas visto que queres criar os mcs de acordo com o numero de links e depois atribuir para cada um deles os nós de cada link, é melhor esquecer esse metodo...

aqui vai entao uma maneira de fazeres isso:

var url:URLRequest=new URLRequest("menu.xml");
var infoXML:URLLoader = new URLLoader();
infoXML.addEventListener(Event.COMPLETE, infoLoaded);
infoXML.load(url);

//definição da variavel mc
var mc:Mc;
// definição / criação do contentor de mcs
var mcContainer:MovieClip = new MovieClip();
//adiciona o contentor á display list
addChild(mcContainer);


function infoLoaded( e:Event ):void
{
//gerar mcs
createMcs( new XML(e.target.data) );
}

//cria os mcs de acordo com o numero de "links" que existem no xml (no teu caso 2)
function createMcs( d:XML ):void
{
var i:uint;
for( i = 0; i < d.children().length(); i++ )
{
	//cria o mc
	mc = new Mc();
	//posiciona o mc
	mc.y = mcContainer.height;

	//define a data do mc (novo xml com as categoria e subcategoria)
	mc.data = new XML( d.children()[i] ) ;

	//adiciona o texto da cetegoria à caixa de texto dinamica do mc...
	mc.texto.text = mc.data.children()[0].@nome;

	/**
	//podes usar tambem este metodo para acederes ao nó "categoria":
	mc.text.text = mc.data.categoria.@nome
	**/

	//adiciona o mc ao contentor (display list)
	mcContainer.addChild(mc);
}
}

Se tiveres duvidas, ou se nao for nada disto que pretendas, avisa,

cumps,

CC


Cumps,

cc

Share this post


Link to post
Share on other sites
coxosclassic

boas,

Pelo exemplo que mostras-te, o codigo que postei faz exactamente isso.

ao criares o mc, estás automaticamente a criar um outro xml dentro desse mc que contem as subcategorias relativamente á categoria desse proprio mc. logo, usando o mesmo codigo podes criar os mcs de subcategorias dentro (ou fora) dos mcs de categorias. :)

Para que finalidade é que queres isso? para fazer um menu (por exemplo)?

cumps,

CC


Cumps,

cc

Share this post


Link to post
Share on other sites
Mysteriis

Sim, estou a tentar criar um menu. Mas esta acontecer-me o seguinte: as subcategorias da mesma categoria estao todas dentro do mesmo movieclip. E eu gostaria de as ter separadas para poder manipula-las como faço com o categorias mc.x=90, mc.y=190+i*15.

var url:URLRequest=new URLRequest("menu.xml");
var infoXML:URLLoader = new URLLoader();
infoXML.addEventListener(Event.COMPLETE, infoLoaded);
infoXML.load(url);

//definição da variavel mc
var mc:Mc;
// definição / criação do contentor de mcs
var mcContainer:MovieClip = new MovieClip();
//adiciona o contentor á display list
addChild(mcContainer);


function infoLoaded( e:Event ):void {
//gerar mcs
createMcs( new XML(e.target.data) );
}

//cria os mcs de acordo com o numero de "links" que existem no xml (no teu caso 2)
function createMcs( d:XML ):void {
var i:uint;
for (i = 0; i < d.children().length(); i++) {
	//cria o mc
	mc = new Mc();
	//posiciona o mc
	mc.x=90;
	mc.y=190+i*15;

	//define a data do mc (novo xml com as categoria e subcategoria
	mc.data=new XML(d.children()[i]);

	//adiciona o texto da cetegoria à caixa de texto dinamica do mc...
	mc.texto.text=mc.data.children()[0].@nome;
	mc.texto2.text=mc.data.subcategoria.@nome;

	/**
    //podes usar tambem este metodo para acederes ao nó "categoria":
   mc.text.text = mc.data.categoria.@nome
	                **/

	//adiciona o mc ao contentor (display list)
	mcContainer.addChild(mc);
}
}

É este o resultado:

http://www.badongo.com/pt/pic/9460250

Share this post


Link to post
Share on other sites
coxosclassic

ok,

então o fluxo do menu que pretendes é algo como isto:

workflow.jpg

certo?

cumps,

CC


Cumps,

cc

Share this post


Link to post
Share on other sites
Mysteriis

Exactamente. Mas as subcategorias tambem vão ser items clicáveis, que depois irão abrir uma "página"...

Share this post


Link to post
Share on other sites
coxosclassic

boas,

ok, sendo assim o problema é bastante simples.

Antes de mais, é melhor esclarecer uma coisa:

A estrutura do teu xml pode (deve) ser melhorada desta maneira:

<menu>
<categoria nome="Porto">
  <subcategoria nome="Edificio Porto A"/>
  <subcategoria nome="Edificio Porto B"/>
  <subcategoria nome="Edificio Porto C"/> 
	</categoria>
	<categoria nome="Lisboa">
  <subcategoria nome="Edificio Lisboa A"/>
</categoria>
</menu>

Não faz muito sentido teres o nó <links>. Imagina isto como as pastas do windows, do mac ou linux:

tens uma pasta Menu (<menu>), dentro dessa pasta tens 2 outras pastas do tipo Categoria (<categoria nome="Porto"> e <categoria nome="Lisboa"> e dentro de cada uma dessas pastas tens as pastas Subcategoria (<subcategoria nome="Edificio Porto A">, etc...)

não só a estrutura faz muito mais sentido para programar, como até na própria leitura do xml por parte de quem o está a ler.

Assim sendo o código para este tipo de menus é bastante linear:

var url:URLRequest=new URLRequest("menu.xml");
var infoXML:URLLoader = new URLLoader();
infoXML.addEventListener(Event.COMPLETE, infoLoaded);
infoXML.load(url);

//definição da variavel mc
var mc:Mc;
// definição / criação do menu categorias (contentor);
var catMenu:MovieClip = new MovieClip();
//adiciona o contentor á display list
addChild(catMenu);

//definição / criação do menu subcategorias (contentor)
var subcatMenu:MovieClip = new MovieClip();
//adiciona o contentor á display list
addChild(subcatMenu);

//referencia do botao actual
var currentMc:Mc;

function infoLoaded( e:Event ):void
{
//criar menu categorias
createMenu( new XML(e.target.data), catMenu );
}

//cria o menu de categorias de acordo com o numero de "categorias" ou "subcategorias" que existem no xml
function createMenu( d:XML, m:MovieClip):void
{
var i:uint;
for( i = 0; i < d.children().length(); i++ )
{
	//cria o mc
	mc = new Mc();
	//posiciona o mc
	mc.y = m.height;

	//define a data do mc (novo xml com as categoria e subcategoria)
	mc.data = new XML( d.children()[i] ) ;

	//adiciona o texto da cetegoria à caixa de texto dinamica do mc...
	mc.texto.text = d.children()[i].@nome;

	//criar event handler para o "click" dos botoes (mc)
	if( m == catMenu )
		mc.addEventListener( MouseEvent.MOUSE_DOWN, catHit );
	else if( m == subcatMenu )
		mc.addEventListener( MouseEvent.MOUSE_DOWN, subcatHit );

	//adiciona o mc ao contentor (display list)
	m.addChild(mc);
}
}

//Event handler para os botoes do menu principal (categoria menu)
function catHit( e:MouseEvent ):void
{
//se por acaso existirem botoes no menu subcategoria, é necessario remove-los para adicionar os novos
removeChild( subcatMenu );

//voltar a criar subcategoria menu
subcatMenu = new MovieClip();
addChild( subcatMenu );
subcatMenu.x = catMenu.width + 20; //por exemplo...

//definir o botao actual
currentMc = e.currentTarget as Mc;

//criar o menu de subcategorias
createMenu( currentMc.data, subcatMenu );
}

//Event handler para os botoes do menu subcategorias
function subcatHit( e:MouseEvent ):void
{
// colocar codigo para abrir conteudo das subcategorias
trace("ir para conteudo: " + e.currentTarget.texto.text);
}

A seguinte imagem exemplifica a estrutura do código de uma maneira mais "grafica" para se perceber melhor:

estrutura.jpg

basicamente tens 2 movieClips que funcionam como "contentores" para os botoes(Mc) das categorias e subcategorias;

o MovieClip catMenu guarda os botoes das categorias, e o subcatMenu guarda os botoes da categoria que seleccionaste.

ao clicares nas categorias, vais refazer o menu subcategorias com a data correspondente... e ao clicares nas subcategorias, iras chamar a pagina ( ou codigo) que queiras.

qualquer alteração de conteudos que queiras fazer (adicionar / remover categorias ou subcategorias) basta fazeres as correcções no ficheiro de XML.

O codigo esta praticamente todo comentado para que possas perceber melhor o que se passa.

Espero que ajude e que tenhas percebido o funcionamento do componente.

Alguma duvida, avisa  :thumbsup:

cumps,

CC


Cumps,

cc

Share this post


Link to post
Share on other sites
Mysteriis

CC, muito obrigado, foste-te excelente em tudo e um bom explicador.

A forma como fiz o xml é que deveria estar confusa e estava a complicar o problema. Eu também não expliquei da melhor forma o problema e deveria ter recorrido mais cedo a esquemas para facilitar a exposição do meu problema.

Muito obrigado pela ajuda e pela atenção.

Cumprimentos

Mysteriis

Share this post


Link to post
Share on other sites
coxosclassic

Optimo!

ainda bem que deu para ajudar e que conseguiste perceber o funcionamento da "coisa". :D

Se tiveres algum problema nao hesites em perguntar, se eu puder ajudo.

Cumps,

CC


Cumps,

cc

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.