Aide - Recherche - Membres - Calendrier
Version complète : Parcourir un XML en le modifiant ?
Centre de Formation Flash - Forums Adobe Flash > Rich media et intégration > Flex
matthieuS
Bonjour,

Je cherche à parcourir tout un fichier XML dont voici le contenu

CODE
<node contentid="0">
    <node contentid="3">
        <node contentid="4">
            <node contentid="1" />
        </node>
    </node>
    <node contentid="8" />
</node>


Et je souhaiterais qu'il deviennent comme ceci :
CODE
<node label="racine" isbranch = "true">
    <node label="groupe1" isBranch = "true">
         <node label="groupe11" isBranch = "true">
        <node label="contenu1" isBranch = "false" />
         </node>
    </node>
   <node label="contenu2" isBranch = "false" />
</node>


Sachant que les labels correspondent au id dans un ARRAY de cette forme
exemple : {label:"racine", id:0},{label:"groupe", id:3}...............

Pour résumer, j'ai un correspondance des id et des label dans un array, avec cela je souhaite convertir une variable XML en une autre variable XML.

Mon principal problème est que je n'arrive pas à trouver le moyen de parcourir le XML pour remplacer le contenu de chaque noeud.

Merci par avance.
matthieuS
Merci pour la réponse rapide

En fait, mon problème est que je n'arrive pas à faire une boucle permettant de parcourir toute l'arborescence du fichier xml

Il faut des FOR imbriqué avec une récupération du parent à chaque fois, et c'est cela que je n'arrive pas à comprendre.
Tonic
Si tu ne connais pas à l'avance la structure de ton xml, tu vas devoir mettre en oeuvre une fonction récursive, ou alors utiliser une boucle de ce genre :

CODE
for each(var result:XML in node..*)
{    

}


matthieuS
Merci

Serait-t-il possible d'avoir un exemple de parcours avec le premier XML que j'ai mis plus haut dans le topic en utilisant for each?

Fusion
CITATION(matthieuS @ Jul 9 2007, 03:27 PM) *
Merci

Serait-t-il possible d'avoir un exemple de parcours avec le premier XML que j'ai mis plus haut dans le topic en utilisant for each?

CODE
for each(var result:XML in node..*)
{    
notepad+=result.toXMLString()+'\n';
}

// plus loin


<mx:TextArea id="notepad" />
matthieuS
Merci pour l'exemple cela parcourt bien le XML mais BIZARREMENT
Voici mon code :
CODE
var notepad:String = new String();
Alert.show(node.toXMLString());
for each(var result:XML in node..*)
{    
    notepad+=result.toXMLString()+'\n';
}
Alert.show(notepad.toString());


J'ai fait des alert.show pour voir le début et la fin, voici les résultat, j'affiche les Alert dans l'ordre du code

voici le xml de départ
CODE
<node>
  <node contentid="3">
    <node contentid="4">
      <node contentid="1"/>
      <node contentid="2"/>
    </node>
    <node contentid="7">
      <node contentid="5"/>
      <node contentid="6"/>
    </node>
  </node>
  <node contentid="8">
    <node contentid="9"/>
    <node contentid="10"/>
  </node>
</node>


voici le xml apres parcours, théorique cela devrait être le même, non???
CODE
<node contentid="3">
  <node contentid="4">
    <node contentid="1"/>
    <node contentid="2"/>
  </node>
  <node contentid="7">
    <node contentid="5"/>
    <node contentid="6"/>
  </node>
</node>
<node contentid="4">
  <node contentid="1"/>
  <node contentid="2"/>
</node>
<node contentid="1"/>
<node contentid="2"/>
<node contentid="7">
  <node contentid="5"/>
  <node contentid="6"/>
</node>
<node contentid="5"/>
<node contentid="6"/>
<node contentid="8">
  <node contentid="9"/>
  <node contentid="10"/>
</node>
<node contentid="9"/>
<node contentid="10"/>


Fusion
En fait si tu vois bien, certains noeuds apparaissent en plusieurs exemplaires. Rien de plus normal, car la formule de Tonic parcourt tous les noeuds.

Ainsi, si un noeud a des enfants, ils apparaissent deux fois : une fois dans le toXMLString de leur père, et une fois quand c'est le toXMLString d'eux-mêmes. Et ainsi de suite ....

Pour faire une récursion plus "contrôlée", utilise les instructions for each( var i:XML in node.*), for each( var i:XML in node.children()), for each( var i:XML in node.descendants()), etc...
matthieuS
Il me faut imbriqué les for alors ?

CODE
for each( var i:XML in node.*) {
     for each( var i:XML in node.children()) {
         for each( var i:XML in node.descendants()) {
              notepad+=result.toXMLString()+'\n';
         }
     }        
}
matthieuS
Merci je viens de comprendre

CODE
for each(var result:XML in node.children())
{    

    notepad+=result.toXMLString()+'\n';

}



Cette boucle parcours bien le XML


Merci à tous pour vos conseils

Fusion
CITATION(matthieuS @ Jul 9 2007, 04:11 PM) *
Il me faut imbriqué les for alors ?

CODE
for each( var i:XML in node.*) {
     for each( var i:XML in node.children()) {
         for each( var i:XML in node.descendants()) {
              notepad+=result.toXMLString()+'\n';
         }
     }        
}


icon_lol.gif Non pas la peine d'imbriquer, c'était un aperçu des commandes qu'on pouvait utiliser.
descendants renvoie une liste XML de tous tes fils, children renvoie un seul niveau de descendance (les fils, mais pas les petits-fils), etc...

Regarde les liens que j'ai mis plus haut, ils expliquent bien comment se servir du XML.

Et je ne sais pas si tu as testé ton code, mais évite d'utiliser trois fois la même variable, ça va mal passer...
matthieuS
Oui j'avais changé les variables

Mais en fait j'ai parlé trop vite, avec

CODE
for each(var result:XML in node.children())
{    

    notepad+=result.toXMLString()+'\n';

}


cela passe que 2 fois dans la boucle, donc c'est toujours pas bon
Décidement les XML, c'est vraiment pas mon truc.
J'arrive pas à trouver le bon parcours en utilisant toutes les méthodes

Biensur je doit mal les utilisés

Je continu à chercher comment parcourir un XML.
Autrement si y'a 8 noeuds, cela doit rentrer 8 fois dans la boucle pour que je puisse modifier chaque noeud, car c'est mon principal but icon_lol.gif
Fusion
Fais une récursion avec les fonctions hasComplexContent() et hasSimpleContent(). La première renvoie true si le neud a des enfants, la deuxième renvoie true si le noeud est une feuille, et réciproquement.

Ca donnerait ceci :

var notepad:String;

public function parcours(xmlContent:XML):void
{
for each(var result:XML in node.children())
{
if (result.hasSimpleContent())
notepad+=result+'\n';
else
parcours(result);

}
}
matthieuS
Merci
je vais tester l'exemple mais node cela vient de xmlContent.node c'est bien cela ?
Fusion
CITATION(matthieuS @ Jul 9 2007, 04:34 PM) *
Merci
je vais tester l'exemple mais node cela vient de xmlContent.node c'est bien cela ?


xmlContent c'est un exemple de nom... C'est le nom de ton noeud racine si tu veux.

matthieuS
Merci
Ok cela commence à devenir pas trop mal

cela parcours presque bien.
Il me manque juste les parent() qui n'apparaissent pas
Fusion
CITATION(matthieuS @ Jul 9 2007, 04:48 PM) *
Merci
Ok cela commence à devenir pas trop mal

cela parcours presque bien.
Il me manque juste les parent() qui n'apparaissent pas


C'est-à-dire? Tu as les feuilles mais pas les noeuds non feuilles?
matthieuS
C'est sympa de m'aider

Voici le xml de départ
CODE
Départ
<node>
  <node contentid="3">
    <node contentid="4">
      <node contentid="1"/>
      <node contentid="2"/>
    </node>
    <node contentid="7">
      <node contentid="5">
        <node contentid="6"/>
        <node contentid="6"/>
      </node>
    </node>
  </node>
  <node contentid="8">
    <node contentid="9"/>
    <node contentid="10"/>
  </node>
</node>


Voici le résultat :
CODE
<node contentid="1"/>
<node contentid="2"/>
<node contentid="6"/>
<node contentid="6"/>
<node contentid="9"/>
<node contentid="10"/>


Comme vous l'avez bien dit, j'ai les feuilles mais pas les noeuds non feuilles
matthieuS
C'est bon j'ai rajouter, l'affectation à notepad dans le else aussi
comme cela j'ai toute les feuilles et tout les noeuds

C'est cool

Merci beaucoup
Bonne soirée
Fusion
CITATION(matthieuS @ Jul 9 2007, 04:34 PM) *
Merci
je vais tester l'exemple mais node cela vient de xmlContent.node c'est bien cela ?


Je viens de comprendre pourquoi tu disais ça, mes excuses. J'ai mis xmlContent dans les paramètres de la fonction et j'utilisais node ensuite -> pas bien icon_razz.gif

Ensuite : pas de 'vous' entre nous. Non mais ! Et en plus je suis peut-être plus jeune icon_cool.gif

Enfin : teste ça :

CODE
    public function parcours(xmlContent:XML):void
    {
        for each(var result:XML in xmlContent.children())
        {
            if (result.hasSimpleContent())
            {
                notepad += result.@contentid+'\n';
                result.@feuille="oui";
            }
            else
            {
                notepad += result.@contentid+'\n';
                parcours(result);
            }

        }
        

    }


Parcourt tous les noeuds, rajoute des paramètres. Cette fonction fait la totale icon_razz.gif
matthieuS
Répondre c'est génial

Car TU (lol) viens en plus de mettre sur la piste de mon but ultime (voir au debut du topic) qui consiste à modifié le noeud xml

Autrement dit, actuellement j'ai un noeud de ce style
<node contentid="4">

et maintenant il me faut trouver la facon de sortir à chaque fois un noeud de ce style
<node label="rlc2" isBranch = "false" />
Tout en conservant l'arborescence, c'est cela le plus dur je pense (garder l'arborescence)

Il me faut changer contentid en label et rajouter isBranch.

A la fin, je dois avoir l'arborescence de départ avec les noeuds modifié.
Galère icon_confused.gif


Fusion
CITATION(matthieuS @ Jul 9 2007, 05:24 PM) *
Répondre c'est génial

Car TU (lol) viens en plus de mettre sur la piste de mon but ultime (voir au debut du topic) qui consiste à modifié le noeud xml

Eh ouais, tu croyais que j'avais oublié ton but ? icon_razz.gif
matthieuS
Dès que je trouve et que j'ai fini je poste la solution finale pour information
Fusion
CITATION(matthieuS @ Jul 9 2007, 05:28 PM) *
Dès que je trouve et que j'ai fini je poste la solution finale pour information


CODE
   public function parcours(xmlContent:XML):void
    {
        for each(var result:XML in xmlContent.children())
        {
            if (result.hasSimpleContent())
            {
                notepad += result.@contentid+'\n';
                result.@isBranch="false";
            }
            else
            {
                notepad += result.@contentid+'\n';
                result.@isBranch="true";
                parcours(result);
            }

        }
        

    }

matthieuS
J'ai fait cela, j'ai l'impression que c'est pareil que toi
Sauf que j'ai des boucles pour remplacer mon contentid par mon label

Et bien j'y suis presque
Il manque à fermer les <node />
car là les noeuds qui contient des feuilles ne sont pas fermé

CODE
public function parcours(xmlContent:XML, listContent:Array):void
        {
            //parcours de tout les noeuds
            for each(var result:XML in xmlContent.children())
            {
                // si le noeud est un feuille
                if (result.hasSimpleContent()){
                      //recherche le label correspond à l'id
                    for( var j:int = 0; j < listContent.length; j++ ){
                        //si le label est égal à l'id alors on remplace    
                        if ( result.@contentid.toString() == listContent[j].id.toString() ){
                            //this.tempTree += listContent[j].label + " " + result.@contentid.toString()+ '\n';
                            //remplacement du noeud par les attributs voulus
                            delete result.@contentid;
                            result.@label = listContent[j].label;
                            result.@isBranch = "false";
                            this.tempTree += "  <node label=" + listContent[j].label.toString() +  " isBranch = false/> \n"
                        }                
                    }
                    //ajout dans un fichier xml    
                    //actTree.appendChild(result);                

                }
                //si le noeud est une branches
                else{
                    //recherche le label correspond à l'id
                    for( j = 0; j < listContent.length; j++ ){
                        //si le label est égal à l'id alors on remplace                        
                        if ( result.@contentid.toString() == listContent[j].id.toString() ){
                            //this.tempTree += listContent[j].label + " " + result.@contentid.toString()+ '\n';
                            //remplacement du noeud par les attributs voulus
                            delete result.@contentid;
                            result.@label=listContent[j].label;
                            result.@isBranch = "true";
                            
                            this.tempTree += "<node label=" + listContent[j].label.toString() +  "isBranch=true > \n"
                            
                        }
                    }
                    //ajout dans un fichier xml
                    //actTree.appendChild(result);
                    parcours(result, listContent);                    
                }
                
            }
        }


j'obtient cela, il manque les <node/> pour les branches et ce sera terminé

CODE
<node label=cdrom_03.swfisBranch=true >
   <node label=cdrom_04.swfisBranch=true >
     <node label=cdrom_01.swf isBranch = false/>
     <node label=cdrom_02.swf isBranch = false/>
   <node label=groupe7isBranch=true >
        <node label=quizz5.swfisBranch=true >
         <node label=bilan6.swf isBranch = false/>
   <node label=groupe8isBranch=true >
      <node label=groupe9 isBranch = false/>
      <node label=Evaluation10 isBranch = false/>
matthieuS
c'est bon

après
parcours(result, listContent);

J'ai rajouté
this.actTree += <node/>


Je te remercie pour ton aide précieuse

Bonne soirée
Atila67
Une autre manière de parcourir ton XML et de le ranger dans un ArrayCollection

http://philflash.inway.fr/flex/dgsimple/srcview/index.html

Look la fonction resultSessionHandler
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'informations, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2008 Invision Power Services, Inc.