• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

creating Array from multilevel XML file

New Here ,
Jan 03, 2011 Jan 03, 2011

Copy link to clipboard

Copied

Hi,

I am working on making an app to display xml data, which currently is using data from parameter file where the data has been stored in array format.

cont = [
         [  {txt:"The Fragrance" } //main menu

         ,[  {txt:"Top Note", frame:"topNote" } ,{txt:"Heart Note", frame:"heartNote" }  ,{txt:"Base Note", frame:"baseNote" } ]// submenu     ]
       
        ,[
          {txt:"The Packaging", frame:"packaging" }// main menu

         ]

]

I have created a xml file and am able to retrieve data, and unable to trace the same.

here is the xml file

<Products>
    <Product txt = "The Fragrance" frame = "">
        <FileName txt = "Top Note" frame = "topNote" ></FileName>
        <FileName txt = "Heart Note" frame = "heartNote" ></FileName>
        <FileName txt = "Base Note" frame = "baseNote" ></FileName>
    </Product>
    <Product txt = "The Packaging" frame = "packaging"></Product>
    <Product txt = "3D Animation" frame = "tvAd" video = "true" flvName = "video.flv" w = "547" h = "309"  ></Product>
    <Product txt = "TThe Advertising" frame = "packaging">
        <FileName txt = "Print Ad Creative Pack" frame = "printCp"></FileName>
    </Product>
</Products>

AS CODE

---------------------------------------

           (GlobalVarContainer.myXML is where is have stored the xml)

            var node:XMLNode=GlobalVarContainer.myXML.firstChild;
            var navItm:int = int(node.childNodes.length);
            for( i=0; i<navItm; i++){               
           
                            var temp_array:Array=new Array();
                            var subnavCount:int=int(node.childNodes.childNodes.length);     //subnav
                            var obj:Object=new Object();                           
                            obj.txt = node.childNodes.attributes['txt']
                            obj.frame = node.childNodes.attributes['frame']
                            //trace(node.childNodes.attributes['txt'])
                           
                                for(var j:int=0;j<subnavCount;j++)
                                    {   
                                    //trace(node.childNodes.childNodes.attributes['txt'])
                                        obj.subtxt=node.childNodes.childNodes.attributes['txt'];
                                        obj.subframe=node.childNodes.childNodes.attributes['frame'];
                                        temp_array.push(obj);
                                    }
                            GlobalVarContainer.my_array.push(temp_array);

}

if I add  - - trace(GlobalVarContainer.my_array);- - to the code the outout is

[object Object],[object Object],[object Object]
[object Object],[object Object],[object Object],
[object Object],[object Object],[object Object],
[object Object],[object Object],[object Object],,,[object Object]

but trace(GlobalVarContainer.my_array.txt +" array"); or trace(GlobalVarContainer.my_array[0].txt +" array"); gives no output.

need guidance to move forward from here.

Thanks,

Ayush

TOPICS
ActionScript

Views

2.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Participant , Jan 04, 2011 Jan 04, 2011

What I meant was that if you load the XML file as e4x you don't have to parse it into an Array to be able to use it. You can extract XMLList from the e4x syntax and use that directly in your code. You can treat the XMLList almost as you treat any Array using a for each loop for instance.

Take the code below as an example and adapt it to your needs:

var mainMenu:XMLList = this.testXML.menu;

for each(var menu:XML in mainMenu) {

     trace("Menu: " + menu.@txt);

     //You can use your main menu item

...

Votes

Translate

Translate
Participant ,
Jan 04, 2011 Jan 04, 2011

Copy link to clipboard

Copied

Hi,

I've tried out the code you listed. but it does not produce the same results. You are only traversing the firstChild of the XML file (the first Product node). Have you tried using e4x instead of manually parsing the xml?

Cheers,

Rui

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 04, 2011 Jan 04, 2011

Copy link to clipboard

Copied

hi Rui,

I tried this method too

var node:XMLNode=GlobalVarContainer.myXML.firstChild;
            var navItm:int = int(node.childNodes.length);
                        for( i=0; i<navItm; i++){   
                            var menu_txt:Array=new Array();
                            var menu_frame:Array=new Array();
                            var submenu_txt:Array=new Array();
                            var submenu_frame:Array=new Array();
                            var menuList:Array =new Array();
                            var submenuList:Array =new Array();
                            var subnavCount:int=int(GlobalVarContainer.naviXML.menu.item.length());     //subnav
                            var obj:Object=new Object();                           
                            menu_txt = GlobalVarContainer.naviXML.menu.@txt.toXMLString()
                            menu_frame = GlobalVarContainer.naviXML.menu.@frame.toXMLString()
                           
                                    for(var j:int=0;j<subnavCount;j++)
                                    {   
                                        submenu_txt=GlobalVarContainer.naviXML.menu.item.@txt.toXMLString();
                                        submenu_frame=GlobalVarContainer.naviXML.menu.item.@frame.toXMLString();
                                    }
                                    menuList = [menu_txt,menu_frame,submenu_txt,submenu_frame];                                                       
                                   
                                    GlobalVarContainer.my_array.push(menuList);
                                        trace(GlobalVarContainer.my_array[0][0]);

                                        if(GlobalVarContainer.my_array[2] !=""){                                     
                                       var mynavItem:Navitem = new Navitem(0, spatie * i, GlobalVarContainer.my_array[0], [i,0], false, true );
                                       this.holder.addChild(mynavItem); // ABLE TO DISPLAY MAIN MENU


                                      
                                      for( j=0; j<subnavCount; j++ ){
                                            var mySubnavItem:Navitem = new Navitem(indent, spatie * ( i + 1 + j ) , GlobalVarContainer.my_array[2], [i,j], true );
                                            this.holder.addChild(mySubnavItem);        // DISPLAYS ONLY THE LAST ENTRY IN THE SUBMENU               
                                        }

}

UPDATED XML

--------------------------------------------------------------------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<products>
    <menu txt="The Fragrance" frame="">
        <item txt="Top Note" frame="topNote" ></item>
        <item txt="Heart Note" frame="heartNote" ></item>
        <item txt="Base Note" frame="baseNote" ></item>
    </menu>
    <menu txt="The Packaging" frame="packaging"></menu>
    <menu txt="The Advertising" frame="packaging">
        <item txt="Print Ad Creative Pack" frame="printCp"></item>
    </menu>
</products>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 04, 2011 Jan 04, 2011

Copy link to clipboard

Copied

What I meant was that if you load the XML file as e4x you don't have to parse it into an Array to be able to use it. You can extract XMLList from the e4x syntax and use that directly in your code. You can treat the XMLList almost as you treat any Array using a for each loop for instance.

Take the code below as an example and adapt it to your needs:

var mainMenu:XMLList = this.testXML.menu;

for each(var menu:XML in mainMenu) {

     trace("Menu: " + menu.@txt);

     //You can use your main menu item creation logic here

     //var mynavItem:Navitem = new Navitem(0, spatie * i, GlobalVarContainer.my_array[0], [i,0], false, true );

     //this.holder.addChild(mynavItem); // ABLE TO DISPLAY MAIN MENU

     var items:XMLList = menu.children();

    

     if(items.length() > 0) {

          for each(var item:XML in items) {

               trace("  Item: " + item.@txt);

               // SubItem creation logic here

               //var mySubnavItem:Navitem = new Navitem(indent, spatie * ( i + 1 + j ) , GlobalVarContainer.my_array[2], [i,j], true );

               //this.holder.addChild(mySubnavItem);        // DISPLAYS ONLY THE LAST ENTRY IN THE SUBMENU      

          }

     }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 06, 2011 Jan 06, 2011

Copy link to clipboard

Copied

hi Rui,

Thanks for the post.. it did help me creating that but unfrtunately cannot use that in this proj.

This is an app which is using array data. the data is stored in array and passed to the navigation as well other components. So changing the complete app is more than asked for. So if its possible for you to suggest a way to create array from the xml to look like this:

cont = [
         [  {txt:"The Fragrance" }     ,[  {txt:"Top Note", frame:"topNote" } ,{txt:"Heart Note", frame:"heartNote" }  ,{txt:"Base Note", frame:"baseNote" } ]     ]
       
        ,[
          {txt:"The Packaging", frame:"packaging" }
         ]
       
        ,[
            {txt:"3D Animation",frame:"tvAd", video:true, flvName:"video.flv",w:547, h:309 }
        ]

]

from the same xml so that i cant read the values from as cont[1], cont[0] and so on

This is the existing  code which uses array from an .as file

if(cont[1]){ // if subnav present
                    var mynavItem:Navitem = new Navitem(0, spatie * i, cont[0], [i,0], false, true );
                    this.holder.addChild(mynavItem);
                   
                    //create subnav
                    for( j=0; j<cont[1].length; j++ ){
                       
                        var mySubnavItem:Navitem = new Navitem(indent, spatie * ( i + 1 + j ) , cont[1], [i,j], true );
                        this.holder.addChild(mySubnavItem);
                   
                    }
               
                } else {
                   
                    if(cont[0].frame == "locate"){
                        var mynavItemExtra:NavitemExtra = new NavitemExtra(0, spatie * i, cont[0], [i,0] );
                        this.holder.addChild(mynavItemExtra);
                    } else {
                        var mynavItem2:Navitem = new Navitem(0, spatie * i, cont[0], [i,0] );
                        this.holder.addChild(mynavItem2);
                    }
                   
                }
               
            }

Thanks and looking for some help

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 06, 2011 Jan 06, 2011

Copy link to clipboard

Copied

It's crazy not to use E4X - but anyway this creates the Array you want:

var xml:XML = <products>
                            <menu txt="The Fragrance" frame="">
                                <item txt="Top Note" frame="topNote" ></item>
                                <item txt="Heart Note" frame="heartNote" ></item>
                                <item txt="Base Note" frame="baseNote" ></item>
                            </menu>
                            <menu txt="The Packaging" frame="packaging"></menu>
                            <menu txt="The Advertising" frame="packaging">
                                <item txt="Print Ad Creative Pack" frame="printCp"></item>
                            </menu>
                        </products>;
           
            var cont:Array = new Array();
           
            for(var i:uint = 0, menuCount:uint = xml.menu.length(); i < menuCount; i++){
                var menuNode:XML = xml.menu;
                var menuArray:Array = [{txt:menuNode.@txt}];
                if(menuNode.child("item").length() > 0){
                    var itemArray:Array = new Array();
                    for(var j:uint = 0, itemCount:uint = menuNode.item.length(); j < itemCount; j++){
                        var itemNode:XML = menuNode.item;
                        itemArray.push({txt:itemNode.@txt, frame:itemNode.@frame});
                    }
                    menuArray.push(itemArray);
                }
                cont.push(menuArray);
            }
           
            trace(cont[0][1][2].frame);

          // traces "heartNote"

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 06, 2011 Jan 06, 2011

Copy link to clipboard

Copied

Hi,

Kenneth's reply is actually more acurate in order to obtain the exact same structure you had  before because my solution inserts an extra object in the mix, so it you really have to replicate it you should use his solution instead.

Cheers,

Rui

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 07, 2011 Jan 07, 2011

Copy link to clipboard

Copied

HI Rui,

Thanks for your input. I tried both the solutions as as your said Kenneth's solution worked in this scenario.

Thanks a lot.

Ayush

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 07, 2011 Jan 07, 2011

Copy link to clipboard

Copied

hi kennethkawamoto2,

your reply worked wonders... THanks a lot...

now i am stuck at another point..

the existing array data looks sumthing like this...

cont = [
         [  {txt:"The Fragrance" }     ,[  {txt:"Top Note", frame:"topNote" } ,{txt:"Heart Note", frame:"heartNote" }  ,{txt:"Base Note", frame:"baseNote" } ]     ]
               
        ,[
        {txt:"Points of Sale", frame:"pointofsales", pof:{x:300, y:473} , points:[    {naam:"dot0", txt:"Store, <font color='#464646'>NYC</font>" },
                                       {naam:"dot1", txt:"Selfridges, <font color='#464646'>London</font>" },
                                       {naam:"dot2", txt:"Bijenkorf, <font color='#464646'>Amsterdam & Rotterdam</font>" },

                ] }
         ]

=====================================================    

If you see the 'Point of Sales' array  you'll find 'points' section. this section again has number of data.

This 'points' array is being called in another function as follow:

for(var _p:uint = 0; _p<cont["points"].length; _p++){
                    
                     var _point:* = _pos.getChildByName(cont["points"][_p].naam);                   
                     _posLocations.push({naam:_point.name,txt:cont["points"][_p].txt});

}

=====================================================

I tried the folowing method:

var cont:Array = new Array();
            var points:Array = new Array();
            var pointsArray:Array = new Array();
            var menuCount:uint=GlobalVarContainer.naviXML.menu.length();
            for (i = 0; i < menuCount; i++) {
               
                var menuNode:XML=GlobalVarContainer.naviXML.menu;
                var menuArray:Array = [{txt:menuNode.@txt, frame:menuNode.@frame,  video:menuNode.@video, flvName:menuNode.@flvName,
                   w:menuNode.@w, h:menuNode.@h, pof:{x:menuNode.@x, y:menuNode.@y}, blank:menuNode.@blank, link:menuNode.@link, points:[points] }];

                if (menuNode.child("item").length()>0) {
                    var itemArray:Array = new Array();
                    var itemCount:uint=menuNode.item.length();
                    for (j = 0; j < itemCount; j++) {
                        var itemNode:XML=menuNode.item;
                        itemArray.push({txt:itemNode.@txt, frame:itemNode.@frame});
                    }
                    menuArray.push(itemArray);
                }
                if (menuNode.child("points").length()>0) {
                    var pointsArray:Array = new Array();
                    var pointsCount:uint=menuNode.points.length();
                    for (j = 0; j < pointsCount; j++) {
                        var pointsNode:XML=menuNode.points;
                        pointsArray.push({naam:pointsNode.@naam, txt:pointsNode});
                    }
                    points.push(pointsArray);
                }

                cont.push(menuArray);
            }

but it doesnt seem to work. Not sure if I am doing it the right way. Please let me know how to achieve this.

===================================================================

I added the points data in the xml as follows

<products>
    <menu txt="The Fragrance" frame="">
        <item txt="Top Note" frame="topNote" ></item>
        <item txt="Heart Note" frame="heartNote" ></item>
        <item txt="Base Note" frame="baseNote" ></item>
    </menu>
    <menu txt="Points of Sale" frame="pointofsales" x="300" y="473">
        <points naam="dot0" ><![CDATA[Store <font color='#464646'>NYC</font>]]></points>
        <points naam="dot1" ><![CDATA[Selfridges <font color='#464646'>London</font>"]]></points>
        <points naam="dot2" ><![CDATA[Bijenkorf <font color='#464646'>Amsterdam & Rotterdam</font>"]]></points>
        <points naam="dot3" ><![CDATA[Galleries Lafayette <font color='#464646'>Berlin</font>"]]></points>
    </menu>

Thanks is advance

ayush

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 07, 2011 Jan 07, 2011

Copy link to clipboard

Copied

            var xml:XML =     <products>
                                <menu txt="The Fragrance" frame="">
                                    <item txt="Top Note" frame="topNote" ></item>
                                    <item txt="Heart Note" frame="heartNote" ></item>
                                    <item txt="Base Note" frame="baseNote" ></item>
                                </menu>
                                <menu txt="Points of Sale" frame="pointofsales" x="300" y="473">
                                    <points naam="dot0" ><![CDATA[Store <font color='#464646'>NYC</font>]]></points>
                                    <points naam="dot1" ><![CDATA[Selfridges <font color='#464646'>London</font>"]]></points>
                                    <points naam="dot2" ><![CDATA[Bijenkorf <font color='#464646'>Amsterdam & Rotterdam</font>"]]></points>
                                    <points naam="dot3" ><![CDATA[Galleries Lafayette <font color='#464646'>Berlin</font>"]]></points>
                                </menu>
                            </products>;
                           
            var cont:Array = new Array();
          
            for(var i:uint = 0, menuCount:uint = xml.menu.length(); i < menuCount; i++){
                var menuNode:XML = xml.menu;
                var menuDataObject:Object = {txt:menuNode.@txt};
                if(menuNode.attribute("frame").toString().length){
                    menuDataObject["frame"] = menuNode.@frame;
                }
                if(menuNode.attribute("x").toString().length && menuNode.attribute("y").toString().length){
                    menuDataObject["pof"] = {x:parseInt(menuNode.@x), y:parseInt(menuNode.@y)};
                }
                var menuArray:Array = [menuDataObject];
                if(menuNode.children().length() > 0){
                    switch (menuNode.child(0).name().toString()) {
                        case "item":
                            var itemArray:Array = new Array();
                            for(var j:uint = 0, itemCount:uint = menuNode.item.length(); j < itemCount; j++){
                                var itemNode:XML = menuNode.item;
                                itemArray.push({txt:itemNode.@txt, frame:itemNode.@frame});
                            }
                            menuArray.push(itemArray);
                        break;
                       
                        case "points":
                            var pointsArray:Array = new Array();
                            for(var k:uint = 0, pointsCount:uint = menuNode.points.length(); k < pointsCount; k++){
                                var pointsNode:XML = menuNode.points;
                                pointsArray.push({naam:pointsNode.@naam, txt:pointsNode});
                            }
                            menuArray[0]["points"] = pointsArray;
                        break;
                    }
                }
               
                cont.push(menuArray);
            }
           
            trace(cont[0][1][2].frame);
            trace(cont[1][0].frame);
            trace(cont[1][0].pof.y);
            trace(cont[1][0].points[2].naam);
            trace(cont[1][0].points[2].txt);

Traces:

baseNote
pointofsales
473
dot2
Bijenkorf <font color='#464646'>Amsterdam & Rotterdam</font>"

I believe this gives you what you want. However, and I know Rui has already suggested this, but let me tell you this approach is just WRONG. This is neither flexible nor robust. You have to modify this script of nested loops every time you change something, and it easily break - if the XML is missing an attribute, for example. People has invented E4X to avoid just this kind of XML parsing. Move on to E4X before this gets even more complex

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 10, 2011 Jan 10, 2011

Copy link to clipboard

Copied

LATEST

Thanks a ton kenneth.. I was able to create what was needed.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 06, 2011 Jan 06, 2011

Copy link to clipboard

Copied

Hi,

I'm glad you found my reply useful. Using the code I've posted it is quite easy to do what you want. Take a look at the changes I made to it and tweak as necessary for your needs.

var cont:Array = new Array();

var mainMenu:XMLList = this.testXML.menu;

for each(var menu:XML in mainMenu) {

     var menuObj:Object = new Object();

     menuObj.txt = menu.@txt.toString();

     menuObj.frame = menu.@frame.toString();

     var items:XMLList = menu.children();

     if(items.length() > 0) {

          menuObj.items = new Array();

          for each(var item:XML in items) {

               var itemObj:Object = new Object();

               itemObj.txt = item.@text.toString();

               itemObj.frame = item.@frame.toString();

               menuObj.items.push(itemObj);

          }

     }

     cont.push(menuObj);

}

Cheers,

Rui

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines