views:

125

answers:

3

I need to get a grip on arrays and XML data but I'm having trouble understanding how to turn xml data into useful data. I was hoping these forums might provide some insight.

I load my XML with this code:

//set values for XML data file
private var XML_URL:String = "http://www.mysite.com/media/locXML.xml";
private var locXML:XML = new XML();

private function getXMLdata():void
{
    var locXMLURL:URLRequest = new URLRequest(XML_URL);
    var locXMLLoader:URLLoader = new URLLoader(locXMLURL);
    locXMLLoader.addEventListener("complete", xmlLoaded);

    function xmlLoaded(event:Event):void
    {
        locXML = XML(locXMLLoader.data);
        trace("Data loaded. " + locXML);
    }
}

I am trying to make the following code into an array populated by that XML data. Everywhere you see a '[]' I need the number to match the number record of the locXML file...

    for each (var point[]:XML in locXML.location)
    {
        pointMarker] = new PointMarker();
        pointMarker[].buttonMode = pointMarker[].useHandCursor = true;
        var image[]:Loader = new Loader();
        image[].load(image[]Req, context);
        image[].x = -iconHeight/2;
        image[].y = -iconWidth/2;
        if (pointMarker[]_motion == true)
        {
            var iconShimmer[]:MovieClip = new IconShimmer() as MovieClip;
            iconShimmer[].x = image[].x;
            iconShimmer[].y = image[].y;
            pointMarker[].addChild(image[]);
            pointMarker[].addChild(iconShimmer[]);
            pointMarker[].pointName[] = point[].name;
            pointMarker[].name = imageBubbleFile[];
        }else{
            pointMarker[].addChild(image[]);
            pointMarker[].pointName[] = point[].name;
            pointMarker[].name = imageBubbleFile[];
        }
        pointMarker[].pointDesc[] = point[].description;
        _map.putMarker(new Location(point[].lat, point[].long), pointMarker[]);
        pointMarker[].addEventListener(MouseEvent.CLICK, pointMarker[]_Click);
        pointMarker[].addEventListener(MouseEvent.ROLL_OVER, pointMarker[]_RO);
        pointMarker[].mouseChildren=false;
    }       
}
}

here is a small snippet of the XML file:

<?xml version="1.0" encoding="utf-8"?>
<root>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<location ID="maplogo">
<name>mapLogo</name>
<lat>31.3731712263342</lat>
<long>-94.08871702323849</long>
<iconFile>town.jpg</iconFile>
<imageFile>type1.swf</imageFile>
<motion>false</motion>
</location>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<location ID="bigstarsupermarket">
<name>Big Star Supermarket</name>
<lat>31.5664202</lat>
<long>-93.4904959</long>
<iconFile>bigStar.jpg</iconFile>
<imageFile>type1.swf</imageFile>
<motion>false</motion>
</location>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
</root>

how can I do that without taking up 2000 lines of code? I was hard coding a number in each one of those '[]' brackets, but that is becoming very painstaking...?

EDIT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~EDIT I changed it to where it will loop during the parsing of the xml. but an error is generated for each of this type formating ["icon"+XMLpCounter]

    public function parseLocXML(nodeName:String, lat:Number, 
         long:Number, iconFile:String, 
         imageFile:String, motion:String):void

    {   
        if (XMLpCounter==0)
        {
        //addMarkers();
        //trace(arguments);
        //trace("--- drawMap ---");
        //trace(arguments.join("\r"));
        XMLpCounter++;
        } else {
        XMLpCounter++;

        //----------------------------------------------------------------------------------------
        var this.["icon"+XMLpCounter]:Loader = new Loader();
        var this.["iconFileLink"+XMLpCounter]:String = mediaLoc + locXML.location.iconFile[XMLpCounter];
        var this.["iconFile"+XMLpCounter+"Req"]:URLRequest = new URLRequest(iconFileLink[XMLpCounter]);
        ["imageFileLink"+XMLpCounter] = mediaLoc + locXML.location.imageFile[XMLpCounter];
        ["imageFile"+XMLpCounter+"Req"] = new URLRequest(imageFileLink[XMLpCounter]);
        ["locPointMarker"+XMLpCounter] = new PointMarker();
        ["locPointMarker"+XMLpCounter].buttonMode = ["locPointMarker"+XMLpCounter].useHandCursor = true;

        ["icon"+XMLpCounter].load(["iconFile"+XMLpCounter+"Req"], context);
        ["icon"+XMLpCounter].x = -iconHeight/2;
        ["icon"+XMLpCounter].y = -iconWidth/2;

and so on
}

ERRORS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ERRORS

var ["icon" + XMLpCounter]:Loader = new Loader();//1084: Syntax error: expecting identifier before left bracket. & 1084: Syntax error: expecting identifier before right bracket.
//var iconFileLink1:String;
//var iconFile1Req:URLRequest;
//var imageFileLink1:String;
//var imageFile1Req:URLRequest;
//obtain from XML the icon for map
var ["iconFileLink"+XMLpCounter]:String = mediaLoc + locXML.location.iconFile[XMLpCounter];//1084: Syntax error: expecting identifier before left bracket. & 1084: Syntax error: expecting identifier before right bracket.
var ["iconFile"+XMLpCounter+"Req"]:URLRequest = new URLRequest(iconFileLink[XMLpCounter]);//1084: Syntax error: expecting identifier before plus. & 1084: Syntax error: expecting identifier before left bracket.
//obtain from XML the ad for bubble
["imageFileLink"+XMLpCounter] = mediaLoc + locXML.location.imageFile[XMLpCounter]; //1084: Syntax error: expecting identifier before assign.
["imageFile"+XMLpCounter+"Req"] = new URLRequest(imageFileLink[XMLpCounter]);//1084: Syntax error: expecting identifier before assign.
["locPointMarker"+XMLpCounter] = new PointMarker();//1084: Syntax error: expecting identifier before assign.
["locPointMarker"+XMLpCounter].buttonMode = ["locPointMarker"+XMLpCounter].useHandCursor = true;//1084: Syntax error: expecting identifier before dot.

["icon"+XMLpCounter].load(["iconFile"+XMLpCounter+"Req"], context);//1084: Syntax error: expecting identifier before dot.
["icon"+XMLpCounter].x = -iconHeight/2;//1084: Syntax error: expecting identifier before dot.
["icon"+XMLpCounter].y = -iconWidth/2;//1084: Syntax error: expecting identifier before dot.

EDIT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~EDIT Everything seems to be working right now except for two issues. At the last bit of the code it adds event listeners to each marker; when the loop gets to the following lines of code, it throws an error(shown below code):

dict["locPointMarker"+i.toString()].addEventListener(MouseEvent.CLICK, ["locPointMarker"+ i.toString()+"_Click"]);
dict["locPointMarker"+i.toString()].addEventListener(MouseEvent.ROLL_OVER, ["locPointMarker"+i.toString()+"_RO"]);

I have also tried this code as follows:

dict["locPointMarker"+i.toString()].addEventListener(MouseEvent.CLICK, ["locPointMarker_Click"+ i.toString()]);
dict["locPointMarker"+i.toString()].addEventListener(MouseEvent.ROLL_OVER, ["locPointMarker_RO"+i.toString()]);

Error #1034: Type Coercion failed: cannot convert []@1488bac1 to Function.

What I would like to do is omit those two last lines and then add the event listeners in a loop at the end. maybe by sending them arguments or something... Is that possible?

+1  A: 

I would suggest to create a variable representing a counter starting at 0 and increment it with each run in the for loop. You can then use the counter to address the entry in the array.

Looking at your code, I'm not even sure if you really need to address the array entries. I think it would be better to create a PointMarker instance within the for loop and then push it onto the array at the end of each run in the loop.

var pointMarkers:Array = [];

for each (var locationXML:XML in locXML.location) {
    var pointMarker:PointMarker = new PointMarker();
    pointMarker.buttonMode = pointMarker.useHandCursor = true;
    ...
    pointMarkers.push(pointMarker);
}       
Christophe Herreman
I actually need other variables to have matching numbers such as this: pointMarker[].pointName[] = point[].name; pointMarker[].name = imageBubbleFile[];
Phil
A: 

I'm having trouble understanding how to turn xml data into useful data.

With the e4x in actionscript XML data is very useful. I have entire applications that run off of XML variables, taken from an XML page much like yours. The speed and ability to query the XML make it easy to work with.

I think you should just stick with the data in XML format, if you need specific things from the data, just query them out. This example would change the source of the icon image to town.jpg

iconImage.source =  locXML.location.(@ID=="maplogo").iconFile;
invertedSpear
this method seems like I would have to type(@ID=="maplogo:) into my flex file instead simply dropping in a new XML file with the same name but different data... is that true? I add and delete locations every week if not 2-3 times a week. I'd rather change the XML and drop it in the file location.
Phil
I think I may be misunderstanding what your intent is. Also that example was just to show how you query XML with e4x. Are you populating a list or something with your XML file?
invertedSpear
my program places markers on a map. The markers are all identified by the XML file (lat/long, icon image, infoBubble, etc) I need to create variables with the data in the xml or just use the data as is. I can load the data and trace the data...but from there I dont know how to separate the data into its various variables
Phil
posting a new answer since it's completely different than this one
invertedSpear
is it possible to slow down the dict loop? I've checked the XML and verified all files exist but it still shows that a load didn't complete. I even wrote a macro program that verifies that all files exist. I don't see why its not following the xml as it is written in the xml.
Phil
its throwing this error:Error #2044: Unhandled IOErrorEvent:. text=Error #2036: Load Never Completed.
Phil
That sounds like a problem with the file loader, one I'm not familiar with since I usually pull my data with HTTPServervices. Should probably post a new question for that one.
invertedSpear
I found out that dict objects has issues with storing something with identical values.
Phil
+1  A: 

I think this will work. Before your for loop create your iterator var.

var i:number = 0;

in your for loop call your variables like this

["pointMarker" + i]. // on first pass this should evaluate to pointMarker0, on second pointMarker1, etc.

At the end of your loop add

i++;

EDIT 2/22: Okay so I just realized that a dictionary is the way to go on this follow this lead:

private function init():void{
    var dict:Object = new Object();
    var i:Number = 0;
    var e:Number = 100;
    for(i;i<e;i++){
        dict["blah" + i.toString()] = i;
    }
    trace(dict["blah3"]); //returns 3
    trace(dict.blah23);//returns 23
}
invertedSpear
I will be trying it this weekend.
Phil
cool, post back with your success, or lack of, so we can help you our further if need be.
invertedSpear
well i have tried this in a number of ways and I am having a problem creating the variables...for example:var ["loader" + i]:loader; will not work
Phil
try giving it a scope: `var this.["loader"+i]`
invertedSpear
ignore my last comment and check out my edit in the answer
invertedSpear
this just might work! I can see the logic behind it. I'll give it a shot!
Phil
This is going to work if we can manage how to fix the only remaining problem....edited above...
Phil
added a possible solution as a comment to the question.
invertedSpear