Has anyone done that yet?
I am a flash developer new to this,
My mission:
- load XML from http and parse the data.
Can someone tell me how to do this? Thanks
Cheers [import]uid: 1995 topic_id: 375 reply_id: 300375[/import]
Has anyone done that yet?
I am a flash developer new to this,
My mission:
Can someone tell me how to do this? Thanks
Cheers [import]uid: 1995 topic_id: 375 reply_id: 300375[/import]
I hope this works
local http = require("socket.http")
local io = require("io");
local ltn12 = require("ltn12")
function parseargs(s)
local arg = {}
string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, \_, a)
arg[w] = a
end)
return arg
end
function collect(s)
local stack = {}
local top = {}
table.insert(stack, top)
local ni,c,label,xarg, empty
local i, j = 1, 1
while true do
ni,j,c,label,xarg, empty = string.find(s, "", i)
if not ni then break end
local text = string.sub(s, i, ni-1)
if not string.find(text, "^%s\*$") then
table.insert(top, text)
end
if empty == "/" then -- empty element tag
table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
elseif c == "" then -- start tag
top = {label=label, xarg=parseargs(xarg)}
table.insert(stack, top) -- new level
else -- end tag
local toclose = table.remove(stack) -- remove top
top = stack[#stack]
if #stack \< 1 then
error("nothing to close with "..label)
end
if toclose.label ~= label then
error("trying to close "..toclose.label.." with "..label)
end
table.insert(top, toclose)
end
i = j+1
end
local text = string.sub(s, i)
if not string.find(text, "^%s\*$") then
table.insert(stack[#stack], text)
end
if #stack \> 1 then
error("unclosed "..stack[stack.n].label)
end
return stack[1]
end
b = http.request( "http://weather.yahooapis.com/forecastrss?p=94089") -- **blah blah use your own url**
x = collect(b); **-- parse xml**
print (x);
local function printTable( t, label, level )
if label then print( label ) end
level = level or 1
if t then
for k,v in pairs( t ) do
local prefix = ""
for i=1,level do
prefix = prefix .. "\t"
end
print( prefix .. "[" .. tostring(k) .. "] = " .. tostring(v) )
if type( v ) == "table" then
print( prefix .. "{" )
printTable( v, nil, level + 1 )
print( prefix .. "}" )
end
end
end
end
printTable(x,nil,3);
[import]uid: 24 topic_id: 375 reply_id: 681[/import]
I can share one very simple way, which I used to read XML yesterday, but there may be a better way.
I parse the XML string using string.match (though I considered using a combo of string.find and string.sub which involves finding the position of a string and using it to parse out the substring)
The following is an XML string (mine is read in from the file system):
<data>
<background id=‘15’/>
<widget id=‘4’/>
</data>
If the string above is a variable called xmlstring then you can grab the id attributes of background and clock with:
local background_id = string.match(xmlstring,"%d",string.find(contents,’<background’))
local widget_id = string.match(xmlstring,"%d",string.find(contents,’<widget’))
The two lines above will grab the first number (%d) following the strings specified (eg. ‘<background’).
background_id should return 15.
For anything more complex you might want to look at some of the Lua libraries from luaforge:
http://luaforge.net/search/?type_of_search=soft&words=xml&Search=Search
I haven’t tried it, but etree Lua library (linked above) makes it look relatively simple dumping XML into a table.
[import]uid: 4418 topic_id: 375 reply_id: 680[/import]
Carlos
That seems to work nicely. How would I pick out particular elements of the xml file, I’d assumed it’s to do with the values passed in printTable( t, label, level ) but this function seems to print the whole file.
Cheers
Gary [import]uid: 4523 topic_id: 375 reply_id: 1286[/import]
Hey, is there a way to skip searching and parsing any data within CDATA tags?
Thanks!
Edit:
Nevermind, edited it myself, seems to work, I’m sure it’s not done very well but if anyone needs it I can post it up. [import]uid: 5708 topic_id: 375 reply_id: 1311[/import]
great, if you can share that would be awesome.
carlos [import]uid: 24 topic_id: 375 reply_id: 1314[/import]
function parseargs(s)
local arg = {}
string.gsub(s, “(%w+)=([”’])(.-)%2", function (w, _, a)
arg[w] = a
end)
return arg
end
function collect(s)
local stack = {}
local top = {}
table.insert(stack, top)
local ni,c,label,xarg, empty
local i, j = 1, 1
local skip = false
local skipvalue
local skipstr
while true do
ni,j,c,label,xarg, empty = string.find(s, “”, i)
if not ni then break end
local text = string.sub(s, i, ni-1)
if string.sub(text,0,9) == “<![CDATA[” then
skip = true
skipvalue = i + string.len(text)
–get start skip value
elseif string.sub(text,-3) == “]]>” then
skipstr = string.sub(s, skipvalue, i-1)
table.insert(top, skipstr)
text=""
skip = false
–get end skip value
end
if not skip == true then
if not string.find(text, “^%s*$”) then
table.insert(top, text)
end
if empty == “/” then – empty element tag
table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
elseif c == “” then – start tag
top = {label=label, xarg=parseargs(xarg)}
table.insert(stack, top) – new level
else – end tag
local toclose = table.remove(stack) – remove top
top = stack[#stack]
if #stack < 1 then
error("nothing to close with "…label)
end
if toclose.label ~= label then
error("trying to close “…toclose.label…” with "…label)
end
table.insert(top, toclose)
end
end
i = j+1
end
local text = string.sub(s, i)
if not string.find(text, “^%s*$”) then
table.insert(stack[#stack], text)
end
if #stack > 1 then
error("unclosed "…stack[stack.n].label)
end
return stack[1]
end
I just added a small skip function, so if CDATA was found then it stops adding stuff until the closing tag of that is found, then it adds all the data inbetween the two areas into a table, I found a html parser which stripped out all the html code from that which made it appear as plain text from that.
I’m not sure how well that is done, I primarily work in Actionscript, only started on lua yesterday pretty much. [import]uid: 5708 topic_id: 375 reply_id: 1325[/import]