Using an XML data provider with the Spark List control in Flex 4

The following example shows how you can use an XML document as a data provider for a Spark List control in Flex 4 by using an XMLListCollection.

Full code after the jump.

The following example(s) require Flash Player 10 and the Adobe Flex 4 SDK. To download the Adobe Flash Builder 4 trial, see www.adobe.com/products/flex/. To download the latest nightly build of the Flex 4 SDK, see opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4.

For more information on getting started with Flex 4 and Flash Builder 4, see the official Adobe Flex Team blog.

<?xml version="1.0"?>
<!-- http://blog.flexexamples.com/2009/11/04/using-an-xml-data-provider-with-the-spark-list-control-in-flex-4/ -->
<s:Application name="Spark_List_dataProvider_XML_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/halo">
 
    <s:List id="lst"
            labelField="@label"
            horizontalCenter="0" verticalCenter="0">
        <s:dataProvider>
            <s:XMLListCollection>
                <fx:XMLList xmlns="">
                    <node label="One" />
                    <node label="Two" />
                    <node label="Three" />
                    <node label="Four" />
                    <node label="Five" />
                    <node label="Six" />
                    <node label="Seven" />
                    <node label="Eight" />
                    <node label="Nine" />
                </fx:XMLList>
            </s:XMLListCollection>
        </s:dataProvider>
    </s:List>
 
</s:Application>

Or, if you wanted to embed the XML into your application, you could use the <fx:XML/> tag and bind to an XMLListCollection, as seen in the following example:

<?xml version="1.0"?>
<!-- http://blog.flexexamples.com/2009/11/04/using-an-xml-data-provider-with-the-spark-list-control-in-flex-4/ -->
<s:Application name="Spark_List_dataProvider_XML_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/halo">
 
    <fx:Declarations>
        <fx:XML id="nodes" source="nodesAndStuff.xml" />
    </fx:Declarations>
 
    <s:List id="lst"
            labelField="@label"
            horizontalCenter="0" verticalCenter="0">
        <s:dataProvider>
            <s:XMLListCollection source="{nodes.children()}" />
        </s:dataProvider>
    </s:List>
 
</s:Application>

And the external .XML file, nodesAndStuff.xml, is as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2009/11/04/using-an-xml-data-provider-with-the-spark-list-control-in-flex-4/ -->
<root>
    <node label="One" />
    <node label="Two" />
    <node label="Three" />
    <node label="Four" />
    <node label="Five" />
    <node label="Six" />
    <node label="Seven" />
    <node label="Eight" />
    <node label="Nine" />
</root>

Or, if you didn’t want to use data binding, Corey, you could set the data provider using ActionScript, as seen in the following example:

<?xml version="1.0"?>
<!-- http://blog.flexexamples.com/2009/11/04/using-an-xml-data-provider-with-the-spark-list-control-in-flex-4/ -->
<s:Application name="Spark_List_dataProvider_XML_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/halo"
        initialize="init();">
 
    <fx:Script>
        <![CDATA[
            private function init():void {
                xmlListColl.source = nodes.children();
            }
        ]]>
    </fx:Script>
 
    <fx:Declarations>
        <fx:XML id="nodes" source="nodesAndStuff.xml" />
    </fx:Declarations>
 
    <s:List id="lst"
            labelField="@label"
            horizontalCenter="0" verticalCenter="0">
        <s:dataProvider>
            <s:XMLListCollection id="xmlListColl" />
        </s:dataProvider>
    </s:List>
 
</s:Application>

This entry is based on a beta version of the Flex 4 SDK and therefore is very likely to change as development of the Flex SDK continues. The API can (and will) change causing examples to possibly not compile in newer versions of the Flex 4 SDK.

20 thoughts on “Using an XML data provider with the Spark List control in Flex 4

  1. Yeah thx, its really usefull :D I’ve been posting on some forums how to load an xml file in flex 4 , and your guide is perfect! :)

  2. One question, is this feature enabled today (4 November, 2009) ? I’m pretty sure I typed in flex 4 <xml and it didn't find anything, now it finds and

  3. Hey Peter… I’m running into problems with the Spark List control and this example. If you use a dataprovider that you add children to, say with a button that calls addChild(), then after about the 7th time of adding a new child to the list, the list overwrites one of the children in addition to adding to the bottom of the list. I’ve checked the XML and it looks accurate (it’s not actually overwriting), but the list displays the children() of the XMLListCollection oddly. Any thoughts as to why this happens?

      1. Hey Peter… I was just checking this page for updates and saw your note. I will try to whip out a quick example test case. Would the best place to post it be here or on the bug that I filed?

      2. I’d say the best place is probably in the official bug base, and then post the bug number here.
        At least that way it will be officially tracked in JIRA (the bug base).

        Thanks,
        Peter

  4. Bug created and example file attached to bug. The bug number is SDK-25486. It appears as if “appendChild” is losing the pointer to the end of the list somehow.

    1. Just an update. I made an example file for that bug to show what the list is doing. It appears that it might not actually the list, but with XMLList.addChild (ala Collection elements) instead. Sorry for the confusion.

      1. @Doug,

        Not sure I really understand the issue (I’m more of an XMLListCollection.addItem() and not an XMLList.appendChild() guy myself), but does this help at all?

        <?xml version="1.0" encoding="utf-8"?>
        <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx">
         
            <fx:Script>
                <![CDATA[
                    import mx.collections.XMLListCollection;
                    import mx.events.FlexEvent;
         
                    private const theXML:XML = <root>
                            <node label="one" value="1 - First"/>
                            <node label="two" value="2 - Second"/>
                            <node label="three" value="3 - Third"/>
                            <node label="four" value="4 - Fourth"/>
                            <node label="five" value="5 - Fifth"/>
                            <node label="six" value="6 - Sixth"/>
                            <node label="seven" value="7 - Seventh"/>
                            <node label="eight" value="8 - Eighth"/>
                            <node label="nine" value="9 - Ninth"/>
                            <node label="ten" value="10 - Tenth"/>
                        </root>;
         
                    private const xmlListOne:XMLList = theXML.node;
         
                    private var indexCounter:Number = 0;
         
                    [Bindable]
                    private var coll:XMLListCollection = new XMLListCollection();
         
                    protected function button1_buttonDownHandler(event:FlexEvent):void {
                        var n:XML = xmlListOne[indexCounter];
                        coll.addItem(n);
                        if (indexCounter < (xmlListOne.length() - 1)) {
                            indexCounter++;
                        } else {
                            indexCounter = 0;
                        }
                    }
         
                    protected function button2_buttonDownHandler(event:FlexEvent):void {
                        xmlValues1.text = coll.source.toXMLString();
                    }
                ]]>
            </fx:Script>
         
            <s:List x="350" y="120" width="232" height="120" labelField="@value" dataProvider="{coll}"/>
            <s:Label x="350" y="99" text="Spark List showing xmlListTwo.appendChild results:"/>
            <s:Label x="51" y="99" text="Original XML:"/>
            <s:Label x="711" y="99" text="Actual xmlListTwo contents:"/>
            <s:Label x="711" y="120" id="xmlValues1"/>
            <s:Button x="476" y="40" label="Add Member to List" buttonDown="button1_buttonDownHandler(event)"/>
            <s:Button x="710" y="40" label="Show Actual XML List" buttonDown="button2_buttonDownHandler(event)"/>
            <s:Label x="51" y="120" id="xmlValues" text="{xmlListOne}"/>	
            <s:Label x="350" y="269" text="Label Control showing xmlListTwo.children():"/>
            <s:Label x="350" y="290" id="xmlValues0"/>
         
        </s:Application>

        Peter

  5. Sorry – am just now seeing your reply. It seems to get around the issue with addChild(). Thanks for suggesting the work-around!

  6. Your examples are far more complex than what I’m trying to do, but I still can’t get it to work right. In Flex 3, you can have an HTTPService grab an XML file as e4x and set your dataprovider of the List to the node you wanted.

    But trying to switch that to s:List completely fails and shows nothing, but without error:

    From what I understand, that is because the e4x object being returned by HTTPService (even s:HTTPService) does not implment the IList interface.

    Question being then: why the hell not?
    Second: What the hell do I do instead? I’ve tried numerous other formats (default object format, XML format, Array, etc) and those do fail with errors. Usually along the lines of not being able to convert ObjectProxy into IList.

    So far for me Flex 4 is a total bust. I thought the goal was to separate the skin from the components, but it seems other features were similarly stripped. I think it is quite obvious that if the mx: example above works, the s: example should also work. It is highly frustrating.

  7. <code>

    </code>

    Trying to post the examples with the code tag, but it’s not working. I see someone else could do it, so here’s my try. I did this post with entity codes for lt and gt.

  8. Hi,
    Can we do the same with Adobe flex builder 3. If possible then please help me i am trying to load external XML file but not able to do that.
    Thanks…..

    1. @munaj ahmad,

      It is definitely possible in Flex 3, the usual gotcha is whether you’re trying to use a node or attribute. You may have to try a labelField of “@label” if you’re using an attribute, or “label” if you’re using nodes.

      Peter

  9. Thanks for the post. This really helped me out. I wasted a ton of time before finding your code.

    Thanks again!

  10. Peter,

    Can you explain the difference between data binding and using Action Script?

    I have an .mxml file with an external .xml file as in your example above. I compiled and the application works, but I need my “configuration” programmers to be able to change the data in the .xml file and see those updates in my application but it isn’t working.

    What am I missing here?

    Thanks.

    Will

    1. Did you get it done’?? i have the same problem i think, the nodes are saved but my combobox does not refresh when i call the httpservice =(

  11. Hey thanks for reading me, i have a huge problem, i´m saving an xml file with fileStream method, after it’s saved, i call the httpService that was saved, but it does not return the last nodes I added, there’s any way i can refresh the httpService so i can show the last info i saved?? please I need this to be done by now, thabk you so much

Comments are closed.