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
obj.subtxt=node.childNodes.childNodes
obj.subframe=node.childNodes.childNodes
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
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
...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
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
submenu_frame=GlobalVarContainer.naviXML.menu.item
}
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>
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
}
}
}
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]
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
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"
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
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
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
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
Copy link to clipboard
Copied
Thanks a ton kenneth.. I was able to create what was needed.
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