Retrieving XML Data and Transforming it into an ArrayCollection of Custom Objects

Once you have gotten the data from the HTTPService you will sometimes need to put this data into a format specific for an application. You will use the new E4X functionality to parse the XML data and place it into an ActionScript array of Product objects so you can use this data structure to display the data. Before the implementation of the E4X functionality, there was no way to work with XML directly in ECMAScript languages. Earlier versions of ActionScript had an XML class, which was not based on the ECMAScript standard, and it was cumbersome and difficult to use because it required complicated looping to obtain the data. The new E4X functionality makes dealing with ActionScript XML objects much easier and more flexible, and uses conventions that should now be familiar to you, such as dot syntax.

After you call the server-side XML using the HTTPService class, you will use E4X functionality to loop through the XML and place the data into an ActionScript array. This is incredibly powerful because it enables you to parse through XML without having to build complicated for loops, as you would if you returned the XML directly as base types. For example, if you had an XML file that contained all the support employees at Adobe and you wanted to view only those employees in Flex technical support, you could use E4X to display only those employees in Flex support. This parsing all happens at the client, so the rest of the employees would still be stored in the client-side data structure for later use. With a regular ActionScript array of objects, you would need to build a complicated series of for loops to obtain the same data.


Using a web browser, browse to the following URL:

This is the same categorized grocery item data as used in the last task.


Open EComm.mxml.


Remove the <mx:Model> tag.

<mx:Model  source="assets/inventory.xml")/> 

Instead of defining your data by embedding an external XML file in the SWF file, you will use the HTTPService class to load in XML data at run time. This is an ideal way of connecting to a database. You can write this middle tier using Cold Fusion, ASP, PHP, or other technologies to convert this data into XML, which Flex can then consume.


Immediately after the current script block, add an <mx:HTTPService> tag and assign it an id of prodByCatRPC. Specify the URL property as the page that you browsed to in the first step.

<mx:HTTPService     url=""/> 

This creates an object with the name of prodByCatRPC from the HTTPService class. When you add this tag, a request is not automatically made to the server. You need to actually execute the request, which you will do soon.


Specify the result handler of the HTTPService to call the prodHandler() function. Pass the result handler the event object. Specify the resultFormat as e4x. The <mx:HTTPService> tag should now look as follows:

<mx:HTTPService     url=""    result="prodHandler(event)"    resultFormat="e4x"/> 

You will use ECMAScript E4X functionality to convert the returned XML into an array of Product objects needed in this application. By specifying e4x as the result format, you are returning native ActionScript XML objects. The HTTPService class also gives you the option of performing the XML-to-Object conversion automatically; you have done this in the first two tasks of this lesson. For now, the ActionScript XML objects will give you more flexibility in dealing with the data.


In the creationComplete event on the <mx:Application> tag, remove the current call to the prodHandler() method, and invoke the send() method of the prodByCatRPC HTTPService object. The <mx:Application> tag should now look as shown here:

<mx:Application xmlns:mx=""    layout="absolute"    creationComplete="prodByCatRPC.send()"> 

Creating the HTTPService object is only the first step in retrieving data, you must also invoke its send() method to actually go and get the data.


At the top of the script block, add an import statement that will import the ResultEvent class.


You need the ResultEvent class to data type the parameter used in the result event handler.


In the script block, locate the prodHandler() method. Change the parameter of the prodHandler() method to accept a parameter named event. Be sure to type this to ResultEvent. Remove all the other code in the method and add a TRace statement that will display the result property of the event object. The prodHandler() method should look as follows:

private function prodHandler(event:ResultEvent):void{    trace(event.result); } 

You changed the function to now be the event handler for the result event of the HTTPService object.


Debug the application. You should see the XML in the Console view from the trace statement.

These are the ActionScript XML objects that are loaded in from the HTTP call. If you had specified object, the Flash Player would have converted the XML into an ArrayCollection automatically. In the next steps you will convert the XML into an array using E4X.


In the prodHandler() method, remove the trace statement and create a new instance of an ActionScript array named prodArray. The prodHandler() method should look as follows:

private function prodHandler(event:ResultEvent):void{    var prodArray:Array = new Array(); } 

The Array class is a native ActionScript data structure that can be used to store complex data. In this case, you will build an array of Product objects, using the value object pattern you worked with in the last lesson. To do this, you will need to build a simple loop that loops through the returned ActionScript XML objects.


Still in the prodHandler() method, immediately after the Array is declared, build a new for loop that iterates through the attributes or properties in the XML objects, as follows:

for each (var p:XML in event.result..product){ } 

The descendant accessor operator represented by a .. provides an easy way for you to access any properties in the XML structure that are stored under the product node, regardless of where the product is in the hierarchical structure. In this case, the product is stored under the category node, but because you are using the descendant accessor (..) operator, you can reference all the information stored in the product node, even though the product node is stored under the category node. It finds the information that you need regardless of where it is in the data structure.

The product node contains all the information that you need to display all the grocery products, including the name, price, image, and so on of each product. You create a new XML object, with the name of p, which stores all the product data for every single node in the XML data structure. It then becomes easy to access the data because the for loop iterates over that data.

Remember that the collection represented by event.result that you are looping over is comprised of the ActionScript XML objects returned by the HTTPService. You have ActionScript XML objects instead of an ArrayCollection because you specified the resultType to be e4x.


Within the for loop, create a new instance of the Product value object with the name of prod and pass it the attributes of the p XML object that it requires. Be sure to cast each attribute to the appropriate base type. Also note that on the isOrganic and isLowFat properties you must do a comparison to the string Yes to convert it to a Boolean.

var prod:Product = new Product ( Number(p.@catID), String(p.@prodName), Number(p.@unitID), Number(p.@cost), Number(p.@listPrice), String(p.@description), Boolean(p.@isOrganic=="Yes"), Boolean(p.@isLowFat=="Yes"), String(p.@imageName)); 

Because this code is located within the for loop that uses the descendant accessor, the attribute sign (@) will display the appropriate attribute for each node of the product XML node. Within the XML there is no mechanism for casting each attribute required by the value object class, so it must be done as the class is being instantiated. The Product class requires typed data, so you must cast each XML attribute as it is coming into the data structure.


Where you did the comparison to the string Yes in creating the new Product, you could have also used the Util.yesNoToBoolean static method. The method is a bit smarter in that it does not care about the case of the string, but the same outcome is achieved either way; TRue or false is placed in the property value instead of Yes or No.


Still inside the for loop, but outside of the Product object declaration, use the push() method of the Array object to add the prod object, which is an instance of the Product class, to the array, as follows:


The push() method of the Array object adds an element to the end of the Array. In this case, the Array is empty, so it will push the instance of the Product class into the first index, index 0, of the Array and continue until it is done looping through all the products in the XML file. This simple code gives you a powerful client-side data structure.


Immediately after the loop, add a TRace statement that will trace the prodArray data structure you just created. The final prodHandler() method should look as follows:

private function prodHandler(event:ResultEvent):void{    var prodArray:Array = new Array();    for each (var p:XML in event.result..product){       var prod:Product = new Product(       Number(p.@catID),       String(p.@prodName),       Number(p.@unitID),       Number(p.@cost),       Number(p.@listPrice),       String(p.@description),       Boolean(p.@isOrganic=="Yes"),       Boolean(p.@isLowFat=="Yes"),       String(p.@imageName));       prodArray.push(prod);    }    trace(prodArray); } 


Save the file and debug the application.

In the Console view, you should see the toString() method of the Product class displays the literal text [Product], followed by the name of each product in the Array. A partial display is shown here:

Adobe Flex 2.Training from the Source
Adobe Flex 2: Training from the Source
ISBN: 032142316X
EAN: 2147483647
Year: 2006
Pages: 225 © 2008-2017.
If you may any questions please contact us: