27
Jul
07

Loading XML at run-time using the mx:HTTPService tag

In the previous post we looked at how to load an XML document in at compile-time and have it embedded in our Flex application. But that technique really only works if the XML data in question never changes. What if you had an XML document that was constantly changing on a daily, or hourly, basis. For example, consider an RSS reader application. If the XML was loaded and embedded in the XML document at compile-time, the RSS would never get updated. And while that may be good in some cases (such as a kiosk, or somewhere without an internet connection where you wanted to display static information), in many cases it may not work.

So, lets take a look at using the mx:HTTPService tag to dynamically load an XML file.

The following example dynamically loads an XML file at run-time using the mx:HTTPService tag, rather than using mx:XML and grabbing the data at compile-time:

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/07/27/loading-xml-at-run-time-using-the-mxhttpservice-tag/ -->
<mx:Application name="HTTPService_resultFormat_test_2"
        xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="top"
        backgroundColor="white"
        creationComplete="tempXML.send();">

    <mx:HTTPService id="tempXML"
            url="xml/cuePoints.xml"
            resultFormat="e4x" />
    <mx:XMLListCollection id="cuePointXMLList"
            source="{tempXML.lastResult.CuePoint}" />
    <mx:XMLListCollection id="parametersXMLList"
            source="{dataGrid.selectedItem.Parameters.Parameter}" />

    <mx:Script>
        <![CDATA[
            private function parametersLabelFunction(item:Object, column:DataGridColumn):String {
                return item.Parameters.Parameter.length();
            }

            private function numericSortCompareFunction(objA:Object, objB:Object):int {
                var itemA:Number = parseInt(objA.Time.text()) as Number;
                var itemB:Number = parseInt(objB.Time.text()) as Number;

                if (itemA > itemB) {
                    return 1;
                } else if (itemA < itemB) {
                    return -1;
                } else {
                    return 0;
                }
            }
        ]]>
    </mx:Script>

    <mx:VBox>

        <mx:DataGrid id="dataGrid"
                dataProvider="{cuePointXMLList}"
                width="100%"
                rowCount="{cuePointXMLList.length + 1}">
            <mx:columns>
                <mx:DataGridColumn id="timeCol"
                        dataField="Time"
                        headerText="Time (ms):"
                        sortCompareFunction="numericSortCompareFunction" />
                <mx:DataGridColumn id="typeCol"
                        dataField="Type"
                        headerText="Type:" />
                <mx:DataGridColumn id="nameCol"
                        dataField="Name"
                        headerText="Name:" />
                <mx:DataGridColumn id="parametersCol"
                        dataField="Parameters"
                        headerText="Parameters:"
                        labelFunction="parametersLabelFunction" />
            </mx:columns>
        </mx:DataGrid>

        <mx:DataGrid id="parametersDataGrid"
                dataProvider="{parametersXMLList}"
                width="100%"
                visible="{parametersXMLList.length > 0}"
                rowCount="{parametersXMLList.length + 1}">
            <mx:columns>
                <mx:DataGridColumn id="parameterNameCol"
                        dataField="Name"
                        headerText="Parameter Name:" />
                <mx:DataGridColumn id="parameterValueCol"
                        dataField="Value"
                        headerText="Parameter Value:" />
            </mx:columns>
        </mx:DataGrid>
    </mx:VBox>

</mx:Application>

xml/cuePoints.xml

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!-- http://blog.flexexamples.com/2007/07/27/loading-xml-at-run-time-using-the-mxhttpservice-tag/ -->
<FLVCoreCuePoints version="1">

    <CuePoint>
        <Time>0</Time>
        <Type>event</Type>
        <Name>slide1</Name>
        <Parameters>
            <Parameter>
                <Name>id</Name>
                <Value>value</Value>
            </Parameter>
        </Parameters>
    </CuePoint>

    <CuePoint>
        <Time>5000</Time>
        <Type>event</Type>
        <Name>slide2</Name>
        <Parameters>
            <Parameter>
                <Name>param1</Name>
                <Value>value1</Value>
            </Parameter>
            <Parameter>
                <Name>param2</Name>
                <Value>value2</Value>
            </Parameter>
        </Parameters>
    </CuePoint>

    <CuePoint>
        <Time>20000</Time>
        <Type>event</Type>
        <Name>slide3</Name>
    </CuePoint>

</FLVCoreCuePoints>

View source is enabled in the following example.

The first thing you notice is that the code is nearly identical to the previous example which used mx:XML. The subtle differences are that instead of mx:XML we used mx:HTTPService to get the data. Also, we now listen for the creationComplete event for on the Application tag where we trigger the XML loading using the HTTPService.send() method. Finally, the locations of the files changed slightly. Now instead of the XML being calculated relative to the MXML file, the XML gets placed relative to the generated SWF file. All the other code stayed the same.

In case you’re curious, the sample XML document in question comes from a Quick Start I wrote for the Flash CS3 release, “Flash Quick Starts: Using the Adobe Flash CS3 Video Encoder“.


3 Responses to “Loading XML at run-time using the mx:HTTPService tag”


  1. 1 Simon Jan 11th, 2008 at 9:33 am

    Note: You also use tempXML.lastResult.CuePoint which is different from the last example.

  2. 2 Gabriel Oct 2nd, 2008 at 4:44 am

    First of all THANK YOU for this new tutorial Peterd.

    Clean, simple…. to much simple maybee i cannot manage make him run.

    Actually it runs but it is not loading anything.

    I have reproduce your workflow again and again and same issue it wont Merge the xml files containing the value on stage.

    FYI i have test others tutorial regarding rss reader or xml injections but still…

    I have check the crossdomain system (for instance i have create a crossdomain.xml file in my local folder allowing “*” all the domains).

    The only thing i am not sure off is my environment
    I am log onto a Microsoft domain.

    thank you for your help if you pass by :)

    Gabriel.

  3. 3 peterd Oct 2nd, 2008 at 9:11 am

    Gabriel,

    I uploaded a SWF and the full source code above.
    The example works for me using the Flex 3.1 SDK, although I was getting some errors/warnings locally when I tested it. After uploading to the site and running over http:// rather than file:///, everything worked fine.

    As for crossdomain issues, you shouldn’t need a crossdomain file if you’re just loading files from your own site. If you are loading remote XML from other sites, the other site would need the crossdomain file on their server.

    Hope that helps,
    Peter

Leave a Reply

This blog is terrible at eating HTML tags. If you plan on posting code/XML, please escape your "<" characters as "&lt;" and your ">" characters as "&gt;".