Flex XML object to ArrayCollection

As I'm working to get my head around how things are done in Flex as opposed to Java and CF, I ran into a situation where I have an XML object that I retrieved from a webservice and I'd like to convert that into an bindable ArrayCollection for use with Lists, Datagrids, etc. I couldn't find a straight answer for this anywhere else, so I figured I would blog about it and help the next person out. As usual, if you disagree or have a better idea let me know as I'm sure there has to be a better way!

To start with, here's the XML we retrieve from the webservice (generated by a CF component):
<?xml version="1.0" encoding="UTF-8" ?>
<scores>
<score position="1">4</score>
<score position="2">1</score>
<score position="3">2</score>
<score position="4">3</score>
<score position="5">5</score>
<score position="6">0</score>
<score position="7">9</score>
<score position="8">6</score>
<score position="9">8</score>
<score position="10">7</score>
</scores>

And here is the code (I'll explain what it does below):
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init()">
<!-- In our demo, this webservice connects to our CF component and retrieves our XML doc -->
<mx:WebService id="scoresRPC"
wsdl="http://agile-solutions.com:81/squares2/cfc/services/squaresService.cfc?wsdl">
<mx:operation name="getVScoresXML" result="scoresHandler(event)" />
</mx:WebService>

<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;

/* This is our bindable ArrayCollection which we fill with the contents
of our XML doc */
[Bindable]
private var scores:ArrayCollection = new ArrayCollection();

/* Temporary placeholder object used when retrieving XML */
private var xmlResult:XML ;

/* Application initializer that kicks off the webservice XML retreival */
public function init():void {
scoresRPC.getVScoresXML.send(1);
}

/* Here's where we make the doughnuts */
/* We loop over all the objects inside the "root.score" node and stuff them each
into the ArrayCollection */
public function scoresHandler(event:ResultEvent):void {
xmlResult = new XML(event.result);

// Convert XML to ArrayCollection
for each(var s:XML in xmlResult.score){
scores.addItem(s);
}

trace("Scores Collection:");
trace(scores);

trace("scores.getItemAt(1): " + scores.getItemAt(0));
}
]]>
</mx:Script>
<mx:Label text="XML Doc to ArrayCollection Demo" fontSize="21"/>
<mx:Label text="Binding Example" textAlign="center" fontSize="17"/>
<mx:List dataProvider="{scores}"></mx:List>
<mx:Spacer/>
<mx:Label text="Retrieve Values Example" textAlign="center" fontSize="17"/>
<mx:Text text="This returns the fifth element in the ArrayCollection (Pun totally intended)"/>
<mx:HBox width="25%" height="10%" horizontalAlign="center">
<mx:Label text="scores.getItemAt(5) =>" textAlign="left" fontWeight="bold"/>
<mx:Text text="{scores.getItemAt(5)}" fontWeight="bold"/>
</mx:HBox>


</mx:Application>


OK, I owe an explanation here but I really need to get back to working on what brought me to this problem in the first place. When I get a chance, I will update this post with a complete explanation. Sorry...

If it helps, here is a forum post in which I was looking for some direction on this matter:
http://tech.groups.yahoo.com/group/flexcoders/message/97710

Comments

Tonya said…
Thank you so much. You truly saved me with this post. I have been fighting with this code for about 3 days until I found your post.

Popular Posts