--[[ /////////////////////////////////////////////////////////////////////////////////////////// 'XMLDocument' Uses LuaXML-0.0.0, From Paul Chakravarti. Available at http://lua-users.org/wiki/LuaXml . I've made some modifications to LuaXML so that it's more flexible. Primarily, I added the ability to parse self-closing tags such as
. Copyright(c) 2005, FreePlay. To use this, please contact me at FreePlayPSP@gmail.com. /////////////////////////////////////////////////////////////////////////////////////////// ]]-- function parseXML(XMLfile) local XMLHandle = assert(io.open(XMLfile, "r")) local XMLData = XMLHandle:read("*all") io.close(XMLHandle) return collect(XMLData) end function parseargs (s) local arg = {} gsub(s, "([%w:]+)=([\"'])(.-)%2", function (w, _, a) arg[w] = a end) return arg end function collect (s) string.gsub(s, "
","\n") --local logfile = assert(io.open("parse.log", "w")) local stack = {n=0} local top = {n=0} tinsert(stack, top) local ni,c,label,args, empty local i, j = 1, 1 while 1 do ni,j,c,label,args, empty = strfind(s, "<(%/?)([%w:]+)(.-)(%/?)>", j) if label ~= nil then label = strlower(label) end --logfile:write("c \""..valOrNil(c).."\" label \""..valOrNil(label).."\" empty \""..valOrNil(empty).."\"\n") if not ni then break end local text = strsub(s, i, ni-1) if not strfind(text, "^%s*$") then tinsert(top, text) end sct = false if c == "" and empty == "/" and label == "" then -- empty element tag tinsert(top, {n=0, label=label, args=parseargs(args), empty=1}) elseif c == "" then -- start tag top = {n=0, label=label, args=parseargs(args)} tinsert(stack, top) -- new level if empty == "/" then --logfile:write("...\n") local toclose = tremove(stack) -- remove top top = stack[stack.n] tinsert(top, toclose) end else -- end tag local toclose = tremove(stack) -- remove top top = stack[stack.n] if stack.n < 1 then --io.close(logfile) error("nothing to close with "..label) end if strlower(toclose.label) ~= strlower(label) then --logfile:write("!!!\n") --io.close(logfile) error("trying to close "..toclose.label.." with "..label) end tinsert(top, toclose) end i = j + 1 end local text = strsub(s, i) --logfile:write("text "..valOrNil(text).."\n") if not strfind(text, "^%s*$") then tinsert(stack[stack.n], text) end if stack.n > 1 then --io.close(logfile) error("unclosed "..stack[stack.n].label) end --logfile:write("done\n") --logfile:close() return stack[1] end