Downloading XML and parsing

I read the tutorial at https://coronalabs.com/blog/2011/07/29/how-to-use-xml-files-in-corona/ and it goes over reading an XML file from an external module. what I am trying to do is access some XML from a website and then parse it for some required information.

I should be able to use that XML parser, but I’m not sure how to get the XML from a website rather than a local file. I would appreciate any pointers as to how to do this.

You use network.request() to get the data.  It will end up in a Lua string that you can then pass to the XML parser to turn it into a Lua table.

Rob

So my network request will be:

local returnstring = network.request(url)

Not sure of the syntax for calling the parser for a variable instead of a file. From the tutorial, I see:

local inbox = xml:loadFile( “sample.xml” )

It won’t be xml:loadFile, but xml:parseXMLText(returnstring)?

network.request does’t return data that way.  It’s an asyncromous function in that it returns to your program right away before the request completes.  You have to provide a call back function (listener) that will be evoked when the request is complete.  Please see:

http://docs.coronalabs.com/api/library/network/request.html

Then something like this?

local function networkListener( event )

    if ( event.isError ) then

        print ( “Network error!”)

    else

       local xmltable=xml:parseXMLText(event.response)

    end

end

network.request( <url goes here>, “GET”, networkListener )

That looks about right…

Rob

My listener function looks like this:

[lua]

        local function networkListener( event )

            if ( event.isError ) then

                print ( “Network error!”)

            else

                local xmltable=xml:ParseXmlText(event.response)

                --print (event.response)

                print (xmltable.child[1].child[1].child[1].value)

                --print (xmltable.child[1].child[1].child[2].value)

            end

        end[/lua]

and the XML string being parsed is this:

This XML file does not appear to have any style information associated with it. The document tree is shown below.

<query xmlns:yahoo=“http://www.yahooapis.com/v1/base.rng” yahoo:count=“2” yahoo:created=“2014-02-07T02:07:33Z” yahoo:lang=“en-US”>

    <results>

        <quote>

            <LastTradePriceOnly>107.45</LastTradePriceOnly>

        </quote>

        <quote>

            <LastTradePriceOnly>97.82</LastTradePriceOnly>

        </quote>

    </results>

</query>

<!--  total: 92  -->

<!--  engine7.yql.bf1.yahoo.com  -->

When I run my code, it seems to work erratically. Sometimes                

print (xmltable.child[1].child[1].child[1].value)

gives me the answer I am looking for. Other times it blows up with an error in the terminal

Runtime error

    …ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:120: attempt to index field ‘?’ (a nil value)

stack traceback:

    [C]: ?

    …ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:120: in function <…ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:112>

Runtime error: …ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:120: attempt to index field ‘?’ (a nil value)

stack traceback:

    [C]: ?

    …ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:120: in function <…ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:112>

Also, when I try and print (xmltable.child[1].child[1].child[2].value) it always gives the run time error.

Any ideas as to why this is happening?

Just solved my own issue. I was looking for the wrong table value. instead of (xmltable.child[1].child[1].child[2].value) the second number is (xmltable.child[1].child[2].child[1].value).

You use network.request() to get the data.  It will end up in a Lua string that you can then pass to the XML parser to turn it into a Lua table.

Rob

So my network request will be:

local returnstring = network.request(url)

Not sure of the syntax for calling the parser for a variable instead of a file. From the tutorial, I see:

local inbox = xml:loadFile( “sample.xml” )

It won’t be xml:loadFile, but xml:parseXMLText(returnstring)?

network.request does’t return data that way.  It’s an asyncromous function in that it returns to your program right away before the request completes.  You have to provide a call back function (listener) that will be evoked when the request is complete.  Please see:

http://docs.coronalabs.com/api/library/network/request.html

Then something like this?

local function networkListener( event )

    if ( event.isError ) then

        print ( “Network error!”)

    else

       local xmltable=xml:parseXMLText(event.response)

    end

end

network.request( <url goes here>, “GET”, networkListener )

That looks about right…

Rob

My listener function looks like this:

[lua]

        local function networkListener( event )

            if ( event.isError ) then

                print ( “Network error!”)

            else

                local xmltable=xml:ParseXmlText(event.response)

                --print (event.response)

                print (xmltable.child[1].child[1].child[1].value)

                --print (xmltable.child[1].child[1].child[2].value)

            end

        end[/lua]

and the XML string being parsed is this:

This XML file does not appear to have any style information associated with it. The document tree is shown below.

<query xmlns:yahoo=“http://www.yahooapis.com/v1/base.rng” yahoo:count=“2” yahoo:created=“2014-02-07T02:07:33Z” yahoo:lang=“en-US”>

    <results>

        <quote>

            <LastTradePriceOnly>107.45</LastTradePriceOnly>

        </quote>

        <quote>

            <LastTradePriceOnly>97.82</LastTradePriceOnly>

        </quote>

    </results>

</query>

<!--  total: 92  -->

<!--  engine7.yql.bf1.yahoo.com  -->

When I run my code, it seems to work erratically. Sometimes                

print (xmltable.child[1].child[1].child[1].value)

gives me the answer I am looking for. Other times it blows up with an error in the terminal

Runtime error

    …ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:120: attempt to index field ‘?’ (a nil value)

stack traceback:

    [C]: ?

    …ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:120: in function <…ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:112>

Runtime error: …ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:120: attempt to index field ‘?’ (a nil value)

stack traceback:

    [C]: ?

    …ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:120: in function <…ers/seandzafovic/Desktop/Volume App 2/data_entry.lua:112>

Also, when I try and print (xmltable.child[1].child[1].child[2].value) it always gives the run time error.

Any ideas as to why this is happening?

Just solved my own issue. I was looking for the wrong table value. instead of (xmltable.child[1].child[1].child[2].value) the second number is (xmltable.child[1].child[2].child[1].value).