john
john

Reputation:

Processing XML in flex3

First time here asking a question and still learning on how to format things better... so sorry about the format as it does not look too well. I have started learning flex and picked up a book and tried to follow the examples in it. However, I got stuck with a problem. I have a jsp page which returns xml which basically have a list of products. I am trying to parse this xml, in other words go through products, and create Objects for each product node and store them in an ArrayCollection. The problem I believe I am having is I am not using the right way of navigating through xml.

The xml that is being returned from the server looks like this:

<?xml version="1.0" encoding="ISO-8859-1"?><result type="success">
<products>
    <product>
        <id>6</id>
        <cat>electronics</cat>
        <name>Plasma Television</name>
        <desc>65 inch screen with 1080p</desc>
        <price>$3000.0</price>
    </product>
    <product>
        <id>7</id>
        <cat>electronics</cat>
        <name>Surround Sound Stereo</name>
        <desc>7.1 surround sound receiver with wireless speakers</desc>
        <price>$1000.0</price>
    </product>
    <product>
        <id>8</id>
        <cat>appliances</cat>
        <name>Refrigerator</name>
        <desc>Bottom drawer freezer with water and ice on the door</desc>
        <price>$1200.0</price>
    </product>
    <product>
        <id>9</id>
        <cat>appliances</cat>
        <name>Dishwasher</name>
        <desc>Large capacity with water saver setting</desc>
        <price>$500.0</price>
    </product>
    <product>
        <id>10</id>
        <cat>furniture</cat>
        <name>Leather Sectional</name>
        <desc>Plush leather with room for 6 people</desc>
        <price>$1500.0</price>
    </product>
</products></result>

And I have flex code that tries to iterate over products like following:

private function productListHandler(e:JavaFlexStoreEvent):void
        {
            productData = new ArrayCollection();
            trace(JavaServiceHandler(e.currentTarget).response);
            for each (var item:XML in JavaServiceHandler(e.currentTarget).response..product )
            {
                productData.addItem( {
                    id:item.id,
                    item:item.name,
                    price:item.price,
                    description:item.desc
                });
            }
        }

with trace, I can see the xml being returned from the server. However, I cannot get inside the loop as if the xml was empty. In other words, JavaServiceHandler(e.currentTarget).response..product must be returning nothing. Can someone please help/point out what I could be doing wrong.

My JavaServiceHandler class looks like this:

package com.wiley.jfib.store.data
{
    import com.wiley.jfib.store.events.JavaFlexStoreEvent;

    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.net.URLLoader;
    import flash.net.URLRequest;

    public class JavaServiceHandler extends EventDispatcher
    {
        public var serviceURL:String = "";
        public var response:XML;

        public function JavaServiceHandler()
        {
        }

        public function callServer():void
        {
            if(serviceURL == "")
            {
                throw new Error("serviceURL is a required parameter");
                return;
            }

            var loader:URLLoader = new URLLoader();
            loader.addEventListener(Event.COMPLETE, handleResponse);
            loader.load(new URLRequest(serviceURL));

//          var httpService:HTTPService  = new HTTPService();
//          httpService.url = serviceURL;
//          httpService.resultFormat = "e4x";
//          httpService.addEventListener(Event.COMPLETE, handleResponse);
//          httpService.send();

        }

        private function handleResponse(e:Event):void
        {
            var loader:URLLoader = URLLoader(e.currentTarget);
            response = XML(loader.data);
            dispatchEvent(new JavaFlexStoreEvent(JavaFlexStoreEvent.DATA_LOADED) );

//          var httpService:HTTPService = HTTPService(e.currentTarget);
//          response = httpService.lastResult.product;
//          dispatchEvent(new JavaFlexStoreEvent(JavaFlexStoreEvent.DATA_LOADED) );

        }

    }
}

Even though I refer to this as mine and it is not in reality. This is from a Flex book as a code sample which does not work, go figure.

Any help is appreciated.

Thanks

john

Upvotes: 0

Views: 732

Answers (7)

Jeremy
Jeremy

Reputation: 3538

I see that you have commented out the use of http service. If you use this object and then specify the result data type of 'OBJECT', which you can access via the static variable 'HTTPService.RESULT_FORMAT_OBJECT'. This will then automatically parse your XML into objects for you. You can then use simple dot notation to access the data rather than looping over the XML.

Once you make this change, run the application using the debugger. Breakpoint your code at the result handler code and take a look at the result data. You should see that your XML has been parsed into an ArrayCollection of ObjectPoxy objects, which you can then loop over and map to your own objects for use in your application.

The benefit here is that the internal parser will handle namespaces, and most other variations of XML you throw at it, without you having to worry about it.

You can lose some performance with large data sets, but of course that only depends on how efficient you can write your own parsing code to be.

Upvotes: 0

BALAJI S Chellappa
BALAJI S Chellappa

Reputation:

I Think you are not created JAvaFlexStoreEVent Here I am Posted full class

package com.wiley.jfib.store.events { import flash.events.Event;

public class javaFlexStoreEvent extends Event
{
    public static const DATA_LOADED:String="onDataLoaded";
    public function javaFlexStoreEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
    {
        super(type, bubbles, cancelable);
    }

}

}

Upvotes: 0

BALAJI S Chellappa
BALAJI S Chellappa

Reputation:

Assign static value for DATA_LOADED in JavaFlexStoreEvent.as

public static const DATA_LOADED:String="onDataLoaded"

Upvotes: 0

user56250
user56250

Reputation:

I just tried following code:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
    creationComplete="onComplete();">

    <mx:Script>
        <![CDATA[
            import radekg.JavaServiceHandler;

            private function onComplete():void {
                var jsh:JavaServiceHandler = new JavaServiceHandler();
                for each ( var node:XML in jsh.response.products.product ) {
                    trace( node.id.text() );
                    trace( node.cat.text() );
                    trace( node.name.text() );
                    trace( node.desc.text() );
                    trace( node.price.text() );
                    trace("---------------------------------------");
                }
            }

        ]]>
    </mx:Script>

</mx:WindowedApplication>

And radekg/JavaServiceHandler.as which emulates your handler class:

package radekg
{
    public class JavaServiceHandler
    {
        public var response:XML = <result type="success">
                    <products>
                        <product>
                            <id>6</id>
                            <cat>electronics</cat>
                            <name>Plasma Television</name>
                            <desc>65 inch screen with 1080p</desc>
                            <price>$3000.0</price>
                        </product>
                        <product>
                            <id>7</id>
                            <cat>electronics</cat>
                            <name>Surround Sound Stereo</name>
                            <desc>7.1 surround sound receiver with wireless speakers</desc>
                            <price>$1000.0</price>
                        </product>
                        <product>
                            <id>8</id>
                            <cat>appliances</cat>
                            <name>Refrigerator</name>
                            <desc>Bottom drawer freezer with water and ice on the door</desc>
                            <price>$1200.0</price>
                        </product>
                        <product>
                            <id>9</id>
                            <cat>appliances</cat>
                            <name>Dishwasher</name>
                            <desc>Large capacity with water saver setting</desc>
                            <price>$500.0</price>
                        </product>
                        <product>
                            <id>10</id>
                            <cat>furniture</cat>
                            <name>Leather Sectional</name>
                            <desc>Plush leather with room for 6 people</desc>
                            <price>$1500.0</price>
                        </product>
                    </products></result>;
    }
}

And as a result I'm getting:

6
electronics
Plasma Television
65 inch screen with 1080p
$3000.0
---------------------------------------
7
electronics
Surround Sound Stereo
7.1 surround sound receiver with wireless speakers
$1000.0
---------------------------------------
8
appliances
Refrigerator
Bottom drawer freezer with water and ice on the door
$1200.0
---------------------------------------
9
appliances
Dishwasher
Large capacity with water saver setting
$500.0
---------------------------------------
10
furniture
Leather Sectional
Plush leather with room for 6 people
$1500.0
---------------------------------------

Your JavaServiceHandler.result points to the XML root tag so in other words, replace your:

for each (var item:XML in JavaServiceHandler(e.currentTarget).response.products..product )

with:

for each (var item:XML in JavaServiceHandler(e.currentTarget).response.products.product )

Hope that helps.

Upvotes: 1

bug-a-lot
bug-a-lot

Reputation: 2454

The root element in your XML is result. So you should have either

for each (var item:XML in JavaServiceHandler(e.currentTarget).response.products..product )

Yes, two dots - no typo there, or (if you know for sure you'll have only product elements):

for each (var item:XML in JavaServiceHandler(e.currentTarget).response.products.children() )

Because you didn't tidy up your XML, you mistook products element for the root, as it took some time for me to notice too. The moral of the story is: always tidy up your XML.

Upvotes: 0

Hrundik
Hrundik

Reputation: 1838

Try looking at JavaServiceHandler(e.currentTarget).response with a debugger. If it IS the XML you're referring to, then your method of accessing product should work. So, it's likely that your Java backend returns not the XML you're expecting.

Try loading the same XML from a simple text file, or simply embed it into a string to make it even more simple:

[Embed (source="xmltest.xml")]
private var xmlTest:String;

And then initialize XML with a var xml:XML = new XML(xmlTest); and try trace(xml..product)

Upvotes: 0

Aethex
Aethex

Reputation: 1502

I'm, not exactly an XML / Flex whiz, but is this a typo?

for each (var item:XML in JavaServiceHandler(e.currentTarget).response..product )

Did you try

for each (var item:XML in JavaServiceHandler(e.currentTarget).response.result.products.product )

That's how I do it. Explicit, explicit, explicit.

Upvotes: 0

Related Questions