Posted By

traeregan on 07/05/09


Tagged

xml


Versions (?)

Who likes this?

5 people have marked this snippet as a favorite

ingorichter
CobaltHex
athanassiadis
Tyster
warhead


Pure Lua XML Parser


 / Published in: Lua
 

URL: http://lua-users.org/wiki/LuaXml

From: Roberto Ierusalimschy

Parses the "main" part of an XML string. It does not handle meta-data. Outputs to a table.

Example: myVar = collect( myXml ) -- myVar would be a table/array of myXml

  1. function parseargs(s)
  2. local arg = {}
  3. string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a)
  4. arg[w] = a
  5. end)
  6. return arg
  7. end
  8.  
  9. function collect(s)
  10. local stack = {}
  11. local top = {}
  12. table.insert(stack, top)
  13. local ni,c,label,xarg, empty
  14. local i, j = 1, 1
  15. while true do
  16. ni,j,c,label,xarg, empty = string.find(s, "<(%/?)(%w+)(.-)(%/?)>", i)
  17. if not ni then break end
  18. local text = string.sub(s, i, ni-1)
  19. if not string.find(text, "^%s*$") then
  20. table.insert(top, text)
  21. end
  22. if empty == "/" then -- empty element tag
  23. table.insert(top, {label=label, xarg=parseargs(xarg), empty=1})
  24. elseif c == "" then -- start tag
  25. top = {label=label, xarg=parseargs(xarg)}
  26. table.insert(stack, top) -- new level
  27. else -- end tag
  28. local toclose = table.remove(stack) -- remove top
  29. top = stack[#stack]
  30. if #stack < 1 then
  31. error("nothing to close with "..label)
  32. end
  33. if toclose.label ~= label then
  34. error("trying to close "..toclose.label.." with "..label)
  35. end
  36. table.insert(top, toclose)
  37. end
  38. i = j+1
  39. end
  40. local text = string.sub(s, i)
  41. if not string.find(text, "^%s*$") then
  42. table.insert(stack[#stack], text)
  43. end
  44. if #stack > 1 then
  45. error("unclosed "..stack[stack.n].label)
  46. end
  47. return stack[1]
  48. end

Report this snippet  

You need to login to post a comment.