Filtering an XML Object In ActionScript to Create Related Combo Boxes in Flex
I attended the 360Flex conference session on using e4x to process XML. I had previously blogged about e4x (see related entries below). However, during the session the presenter covered how to filter XML. I had forgotten about this capability. I decided to create a quick example of where filtering XML might be useful since I'd not blogged about it before.
My example (right click on the Flex application to view the source) filters an XML object to create XMLList objects that are used to provide data for combo boxes that are related. If you select the car manufacturer in the first combo box, the cars and trims listed in the other two combo boxes change. e4x's filtering commands make creating these related combo boxes simple.
My reference for this example is Programming ActionScript 3.0, chapter 11 ( page 311), Working With XML.
To filter an XML object, you use the parentheses operators. Within the parentheses you create an expression that evaluates to true or false. You can filter the XML to create an XMLList based on either the name or attribute values. To filter the XML based on the name value, you could do the following:
companies.(company == 'ebay')
The above would return all the company elements where the company value is equal to 'ebay'.
You can also filter the XML based on an attribute's value:
companies.company.(@name == 'ebay')
The above would return all the company elements where the name attribute value is equal to 'ebay'.
In my example I filter the XML using the attribute values. When filtering an XML object, the elements returned by applying the filter can be used to create an XMLList object. For example, I create the following XML list object:
carNameList = cars.car.(@manufacturer == manufacturerNames.selectedLabel).model.@name;
The carNameList is an XMLList that contains just the values for every name attribute where the manufacturer attribute equals the label the user selected in a combo box. I can then use this XMLList object to create an XMLListCollection, which can be the data provider for another combo box:
carNameListCol = new XMLListCollection(carNameList);
Since I made the XMLListCollection objects bindable, when I change them, the values displayed by the combo boxes will change.
e4x is a powerful, but easy way to manipulate XML objects in ActionScript 3.0. Consult the Flex and ActionScript references for more tutorials and information.
Thanks
Bruce
After working on this stuff for a while longer, I've discovered that there is a cleaner means of achieving this same result.
Here's a (incomplete, hopefully clear) alternate approach to your sample program. The two keys are (1) that the comboBox redraws itself when the data provider is changed, and (2) the dataprovider will cast a E4X XML value to a XMLListCollection on assignment.
Hope this helps (sure wish Adobe provided more extensive programming patterns for this)....
jr
[Bindable] private var cars:XML = “<cars>…</cars>”;
private function refreshTrim():void {
trimNamesCB.dataProvider = cars.car.model.(@name == carNames.selectedLabel).trim ;
}//end function refreshTrim
<mx:Panel width=”80%” height=”80%“>
<mx:HBox>
<mx:Label text=”Trim” />
<mx:ComboBox id=”trimNamesCB” dataProvider=”{cars.car[0].model[0].trim}” />
</mx:HBox>
</mx:Panel>