Transformer xml en objet --> AS3

Résolu
cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 - 7 juin 2009 à 15:06
cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 - 9 juin 2009 à 12:22
Bonjour,
avant toute chose, désolé pour ce long bout de code.
J'essaie de créer des objets dans un tableau à partir d'un XML
Le XML est de la forme :
<client id= "dasco">
    <site identifiant="dasco1">
        <titre letitre="Le site 1">
        <etat>attente</etat>
        13 rue du site 75010 Paris
        <texte>dasco/texte/texte1.txt</texte>
        <carte>swf/plan1.swf</carte>
        dasco/image/img1.jpg
        dasco/image/img2.jpg
        dasco/image/img3.jpg
        dasco/plan/plan1.jpg

        dasco/plan/plan2.jpg

    </site>
</client>

Avec plusieurs sites. Le nombre des images n'est pas le même à chaque site, pas plus que le nombre de plan (planint)
Je ne sais d'ailleurs pas s'il est préférable de différencier les balises images ou pas ... c'est en quelques sorte une première question.

Mon as est le suivant (tout du moins la partie relative au xml ):
private function completeHandler(eventObj:Event):void {
    trace("lance XML !!!");
    languageXML = new XML(eventObj.currentTarget.data);
    //trace("languageXML = "+languageXML);//renvoi le XML entier
    //définition du client  --> permet normalement de définir les chantier dans l'animation
    client=languageXML.attributes();
    //trace("client = "+client);
    var currentLangNode:XMLList = languageXML.children();
    //trace("currentLangNode = "+currentLangNode);//--> BON :: Renvoie le XML dans root ou 6 avec .length() (nombre de noeuds)
    nbreSite=currentLangNode.length();
    //trace("nombre de site = "+nbreSite);
    /////////////////////////////////////////////////////////////////////    Bon au dessus
           
    //trace("currentLangNode[0] = "+currentLangNode[0]);//--> renvoie les éléments du premier site
    var i:int = 0;
    var childNode:XML;//
    var node:XML;
    var j:int = 0;
    for each (childNode in currentLangNode) {
                //  Création du tableau de base
                masterArray[i] = new Array();
                //   Utilisation du premier noeud
                masterArray[i][j]=new Object();
                masterArray[i][j].name = childNode.attributes();// ----> renvoi l'identifiant du site
                trace("masterArray["+i+"]["+j+"] = "+masterArray[i][j]);       

                var nodeNode:XML;
                var k:int = 0;
                for each (node in childNode.children()) {
                    trace("node.name = "+node.name());// renvoie le nom de la balise
                    for each (nodeNode in node.children()) {                        trace("nodeNode "+node.name()+" "+nodeNode);
                        //Créer l'object ici ???????
                    }
                }
            }
    trace("2. masterArray = "+masterArray);
}

Le XML est bien chargé, j'arrive à l'afficher en entier par une fonction trace, à trouver le nombre de sites...
Mais je n'arrive pas créer un tableau qui contiendrait les éléments sites, chaque élément site étant un object qui contiendrait l'ensemble des données d'un site.

Et ça fait des heures que je tourne en rond. Je ne sais plus par ou prendre le problème, d'autant plus que je ne suis pas une flèche en XML.
Si quelqu'un peut me donner une piste, un tuyau, me dire si je suis complètement à côté de la plaque...

Merci d'avance pour votre attention et vos conseils.
Denis

Tout vient à qui sait attendre

11 réponses

cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 2
7 juin 2009 à 20:08
Bon
je ne suis pas sur de l'élégance de la fonction... mais ELLE FONCTIONNE

private function completeHandler(eventObj:Event):void {
            trace("lance XML !!!");
            languageXML = new XML(eventObj.currentTarget.data);
            //trace("languageXML = "+languageXML);//renvoi le XML entier
            //définition du client  --> permet normalement de définir les chantier dans l'animation
            client=languageXML.attributes();
            //trace("client = "+client);
            var currentLangNode:XMLList = languageXML.children();
            //trace("currentLangNode = "+currentLangNode);//--> BON :: Renvoie le XML dans root ou 6 avec .length() (nombre de noeuds)
            nbreSite=currentLangNode.length();
            //trace("nombre de site = "+nbreSite);
            /////////////////////////////////////////////////////////////////////    Bon au dessus
           
            for(var i:int=0; i<nbreSite; i++){
                masterArray[i]={titre:languageXML.site[i].titre, etat:languageXML.site[i].etat, adresse:languageXML.site[i].adresse,
                texte:languageXML.site[i].texte, carte:languageXML.site[i].carte, image1:languageXML.site[i].image1, image2:languageXML.site[i].image2,
                image3:languageXML.site[i].image3, planint1:languageXML.site[i].planint1, planint2:languageXML.site[i].planint2};
            }
//les vérifs
            trace("masterArray = "+masterArray);
            trace("masterArray[1].texte = "+ masterArray[1].texte);
        }

Par contre, si je ne peux pas avoir un XML où chaque "collection" est identique en forme à la suivante... je l'aurais dans le ...

Autrement dit, dans le fond le problème reste entier. Mais au moins, j'ai une base de travail !

Merci inaden pour ton aide !
Et que cela serve à d'autre !

Tout vient à qui sait attendre
3
pegase31 Messages postés 6138 Date d'inscription dimanche 21 décembre 2003 Statut Modérateur Dernière intervention 4 septembre 2013 12
8 juin 2009 à 15:58
Rien de bien dramatique et en quelques lignes tu peux sortir toutes les infos dont tu as besoin !

Partons donc du principe que ton XML est chargé et placé dans "languageXML"

Voilà quelques exemples qui pourrons te montrer comment ressortir les données trés ciblées en une ligne (un XMLList forcément)

LanguageXML.@id; //renvoie "dasco1"
LanguageXML.site.(@identifiant=="dasco1"); //renvoie le noeud complet ciblé

addmettons que : target:XMLList = LanguageXML.site.(@identifiant=="dasco1");

target.@titre; //renvoie "Le site 1"
target.@etat; //renvoie "chantier"
etc ...

Un truc à savoir : ne jamais utiliser de variables de comparaisons ayant le même nom qu'un noeud du XML :

site:String = "dasco1";
target:XMLList = LanguageXML.site.(@identifiant==site); //ne ciblera rien, car il y aura soucis entre le noeud "site" et le string "site" .. donc sortie null

Voilà, tu sais tout (ou presque)

Peg'
3
cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 2
7 juin 2009 à 16:10
Bon, j'essaie de faire évoluer ma boucle :
for each (childNode in currentLangNode) {
                    masterArray[i] = childNode.attributes();
                    trace("ddjfdhfdjhf = "+masterArray[i]);
                    tableauSite[i]=new Object();
                    tableauSite[i].name=masterArray[i];
}
Le trace ddjfd... donne
ddjfdhfdjhf = dasco1
ddjfdhfdjhf = dasco2
ddjfdhfdjhf = dasco3
Ce qui me réjouit, mais si ensite je fais
trace("tableauSite[0] = "+tableauSite[0]+" et son nom est : "+tableauSite[0].name);
J'obtiens :
tableauSite[0] = [object Object] et son nom est : dasco3
Ce qui ne m'arrange pas, puisque cela devrait être mon dasco1

Si quelqu'un n'est pas devant le tennis... et a une idée.

Tout vient à qui sait attendre
0
cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 2
7 juin 2009 à 19:22
Bon, c'est laborieux, voilà ou j'en suis au niveau de ma (mes) boucle(s) :

var childNode:XML;
            //for(var i:int=0; i<nbreSite; i++){
                //trace("currentLangNode["+i+"] = "+currentLangNode[i]);//--> renvoie les éléments du premier site
            //}
                for each (childNode in currentLangNode) {
                    masterArray.push(childNode.attributes());
                }

            trace("masterArray = "+masterArray);
                for(var i:int=0; i<nbreSite; i++){
                    masterArray[i] as Object;
                    trace("masterArray["+i+"] = "+masterArray[i]);
                    //vérification que les dacos sont bien des objets  --- > ok
                    //if(masterArray[i] is Object){
//                        trace("object");
//                    }
//                    else{trace("pas object");}
                    var node:XML;
                    var nodeNode:XML;
                    var k:int = 0;
                    for each (node in childNode.children()) {
                        trace("node.name = "+node.name());// renvoie le nom de la balise
                        for each (nodeNode in node.children()) {                            trace("nodeNode "+node.name()+" "+nodeNode);
                        }
                    }
                }

Ce qui fait que j'ai bien mes trois objects. J'ai aussi changer mon XML de tel sorte que tous les sites aient la même architecture quittes à ce que certaines balises soient vides (exemple en fin de message).
Le problème est que j'aimerais maintenant remplis mes objets de chacune des différentes balises pour avoir un truc qui serait (pour aller avec l'exmeple) :
dasco2={titre:"le deuxième site , etat:"attente", adresse:"24 rue du deuxième site 75010 Paris ....}
Ce qui me donnerais au final :
masterArray=[{le premier objet},{le second objet tel que défini ci-dessus}...]

Si quelqu'un a une idée et que cette idée est bonne, il recevra un tonneau de pif !

<client id="dasco">
<site identifiant="dasco2">
        <titre>Le deuxième titre</titre>
        <etat>attente</etat>
        24 rue du deuxième site 75010 Paris
        <texte>dasco/texte/texte1.txt</texte>
        <carte>swf/plan1.swf</carte>
        dasco/image/img4.jpg
        dasco/image/img5.jpg
       
        dasco/plan/plan3.jpg

       

    </site>
... les autres istes et </client>

Tout vient à qui sait attendre
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
pegase31 Messages postés 6138 Date d'inscription dimanche 21 décembre 2003 Statut Modérateur Dernière intervention 4 septembre 2013 12
7 juin 2009 à 21:00
Oh là là .... la prise de tête sur un simple XML !

Moi je te conseille vivement d'oublier ton traitement AS2 du XML pour t'intéresser à l'E4x de l'AS3 ... car un noeud XML en as3 EST un objet ...
Je n'ai pas lu ton code jusqu'au bout, mais si tu pouvais nous expliquer simplement et sans code ce que tu cherches à ressortir et sous quels critères du xml que tu as, je te donnerais les façons de t'y prendre en quelques lignes, simplement.

Car on ne peut pas repartir de ton code, tellement il n'est pas adapté et trop axés AS2.

Peg'

Ps: pour simplifier: donne le XML en l'état et ce que tu veux avoir en fonction de quoi.
0
cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 2
8 juin 2009 à 08:57
Salut Peg' et merci de ton soutiens.
Voilà, le truc est que normalement je dois récupérer un xml comportant principalement des url et quelques champs textes a priori de la forme :
<client id="dasco">
    <site identifiant="dasco1">
        <titre>"Le site 1"</titre>
        <etat>chantier</etat>
        13 rue du site 75010 Paris
        <texte>dasco/texte/texte1.txt</texte>
        <carte>plan/plan1.swf</carte>
        dasco/image/img1.jpg
        dasco/image/img2.jpg
        dasco/image/img3.jpg
        dasco/plan/plan1.jpg

        dasco/plan/plan2.jpg

    </site>
Avec évidemment plusieurs sites. L'id client est important car il déterminera ce qui est visible dans l'animation (ce sont des plans autocad mis dans flash avec des chantiers et des données sur ces chantiers).
Le "titre" et la "carte" me permettent de remplir un combobox. Les autres données permettent d'appeler des remarques, photos et plans lié au chantier. Dans mon idée, je voulais créer un tableau (peut-être qu'un vector serait mieux), comportant des objets, chaque objet étant un site.
Normalement, le nombre d'image ou de plan n'est pas forcement le même pour chaque site, ce qui me pose aussi un problème que j'ai "résolu" en mettant des balises vides pour que chaque site ait le même nombre de balise.
Comme c'est mon premier gros boulot en Flash (et que j'ai besoin de nuts !), il me fallait vite une solution pour pouvoir dire : c'est ok, je peux le faire. Après hésitation, j'ai décidé de le faire en as3 (il faut bien essayé d'évoluer), et pour le reste de l'interactivité, j'en suis bien content !
Enfin, pour la forme du XML, je peux demander à ce qu'il prenne une autre forme, si une autre forme est plus pratique.
Voilà, j'espère être compréhensible. En tout cas, merci de ton aide.

Tout vient à qui sait attendre
0
cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 2
8 juin 2009 à 18:33
Mais, ça m'a l'air très simple... c'est fou !
Bon, reste à mettre en chantier cette simplicité...
Bon, j'essaie de mettre ça en pratique dès demain matin. Merci bien. Je te tiens au courant.
Que ferions-nous sans toi !
Encore merci

Tout vient à qui sait attendre
0
cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 2
9 juin 2009 à 08:13
Salut,
Comme je le suggérais... la simplicité une fois mise en chantier s'avère toujours moins simple.
Deux problèmes :
Ma fonction :
private function completeHandler(eventObj:Event):void {
            trace("lance XML !!!");
            languageXML = new XML(eventObj.currentTarget.data);

            client=languageXML.@id;
            trace("client = "+client); //ça c'est ok
           
            trace("LanguageXML.@id = "+languageXML.@id);
            trace(languageXML.@id is String);*/// à moins que je m'abuse, j'ai un false ici
           var target:XMLList = languageXML.site.(@identifiant=="dasco1");
            trace("target = "+target);//renvoie tout dasco1
            trace("target.@identifiant = "+target.@identifiant);//renvoie dasco 1
            trace("le titre de dasco1 est "+target.@titre);//ne renvoie rien à part le texte entre guillemets
            trace("le chantier de dasco1 est "+target.@chantier);//ne renvoie rien à part le texte entre guillemets
}

Donc le problème est que target.@titre ne renvoie rien
Et il faut, une fois que cela renverra quelque chose que je trouve un moyen de parcourir mon XML par une boucle (for each ???).
Donc, si quelqu'un a une idée. Merci d'avance

Tout vient à qui sait attendre
0
pegase31 Messages postés 6138 Date d'inscription dimanche 21 décembre 2003 Statut Modérateur Dernière intervention 4 septembre 2013 12
9 juin 2009 à 11:25
ah oui, autant pour moi, il faut enlever le @, car c'est un attribut

donc : target.titre renvoie "Le site 1" (sans le @)

Mais toutes les données des attributs et des contenus de noeuds sont déjà des Strings, et ne peuvent rien contenir d'autre. donc pas besoin des "" ...

Peg'
0
cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 2
9 juin 2009 à 12:14
Ok, merci
Je reviendrais peut-être pour ma boucle.
En tout cas, cela à l'air très pratique !!!

Tout vient à qui sait attendre
0
cs_inaden Messages postés 618 Date d'inscription mercredi 4 avril 2007 Statut Membre Dernière intervention 27 août 2010 2
9 juin 2009 à 12:22
Génial... Merci
Il faut que je trouve un tonneau de pif pour toi !
La boucle fonctionne, tout est merveilleux, la vie est belle malgré tout ce qu'il y a de moche en ce bas monde (au moins pour les dix minutes à venir ) !!!
Mille merci

Tout vient à qui sait attendre
0
Rejoignez-nous