PageRenderTime 50ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/Code/xml.lua

https://bitbucket.org/AleksanderGrzyb/cybairbot-festival-application
Lua | 121 lines | 96 code | 9 blank | 16 comment | 13 complexity | 13f1ad0e72790a40510ac0f1fb74de97 MD5 | raw file
  1. module(..., package.seeall)
  2. ---------------------------------------------------------------------------------
  3. ---------------------------------------------------------------------------------
  4. --
  5. -- xml.lua - XML parser for use with the Corona SDK.
  6. --
  7. -- version: 1.1
  8. --
  9. -- CHANGELOG:
  10. --
  11. -- 1.1 - Fixed base directory issue with the loadFile() function.
  12. --
  13. -- NOTE: This is a modified version of Alexander Makeev's Lua-only XML parser
  14. -- found here: http://lua-users.org/wiki/LuaXml
  15. --
  16. ---------------------------------------------------------------------------------
  17. ---------------------------------------------------------------------------------
  18. function newParser()
  19. XmlParser = {};
  20. function XmlParser:ToXmlString(value)
  21. value = string.gsub (value, "&", "&"); -- '&' -> "&"
  22. value = string.gsub (value, "<", "&lt;"); -- '<' -> "&lt;"
  23. value = string.gsub (value, ">", "&gt;"); -- '>' -> "&gt;"
  24. value = string.gsub (value, "\"", "&quot;"); -- '"' -> "&quot;"
  25. value = string.gsub(value, "([^%w%&%;%p%\t% ])",
  26. function (c)
  27. return string.format("&#x%X;", string.byte(c))
  28. end);
  29. return value;
  30. end
  31. function XmlParser:FromXmlString(value)
  32. value = string.gsub(value, "&#x([%x]+)%;",
  33. function(h)
  34. return string.char(tonumber(h,16))
  35. end);
  36. value = string.gsub(value, "&#([0-9]+)%;",
  37. function(h)
  38. return string.char(tonumber(h,10))
  39. end);
  40. value = string.gsub (value, "&quot;", "\"");
  41. value = string.gsub (value, "&apos;", "'");
  42. value = string.gsub (value, "&gt;", ">");
  43. value = string.gsub (value, "&lt;", "<");
  44. value = string.gsub (value, "&amp;", "&");
  45. return value;
  46. end
  47. function XmlParser:ParseArgs(s)
  48. local arg = {}
  49. string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a)
  50. arg[w] = self:FromXmlString(a);
  51. end)
  52. return arg
  53. end
  54. function XmlParser:ParseXmlText(xmlText)
  55. local stack = {}
  56. local top = {name=nil,value=nil,properties={},child={}}
  57. table.insert(stack, top)
  58. local ni,c,label,xarg, empty
  59. local i, j = 1, 1
  60. while true do
  61. ni,j,c,label,xarg, empty = string.find(xmlText, "<(%/?)([%w:]+)(.-)(%/?)>", i)
  62. if not ni then break end
  63. local text = string.sub(xmlText, i, ni-1);
  64. if not string.find(text, "^%s*$") then
  65. top.value=(top.value or "")..self:FromXmlString(text);
  66. end
  67. if empty == "/" then -- empty element tag
  68. table.insert(top.child, {name=label,value=nil,properties=self:ParseArgs(xarg),child={}})
  69. elseif c == "" then -- start tag
  70. top = {name=label, value=nil, properties=self:ParseArgs(xarg), child={}}
  71. table.insert(stack, top) -- new level
  72. else -- end tag
  73. local toclose = table.remove(stack) -- remove top
  74. top = stack[#stack]
  75. if #stack < 1 then
  76. error("XmlParser: nothing to close with "..label)
  77. end
  78. if toclose.name ~= label then
  79. error("XmlParser: trying to close "..toclose.name.." with "..label)
  80. end
  81. table.insert(top.child, toclose)
  82. end
  83. i = j+1
  84. end
  85. local text = string.sub(xmlText, i);
  86. if not string.find(text, "^%s*$") then
  87. stack[#stack].value=(stack[#stack].value or "")..self:FromXmlString(text);
  88. end
  89. if #stack > 1 then
  90. error("XmlParser: unclosed "..stack[stack.n].name)
  91. end
  92. return stack[1].child[1];
  93. end
  94. function XmlParser:loadFile(xmlFilename, base)
  95. if not base then
  96. base = system.ResourceDirectory
  97. end
  98. local path = system.pathForFile( xmlFilename, base )
  99. local hFile, err = io.open(path,"r");
  100. if hFile and not err then
  101. local xmlText=hFile:read("*a"); -- read file content
  102. io.close(hFile);
  103. return self:ParseXmlText(xmlText),nil;
  104. else
  105. print( err )
  106. return nil
  107. end
  108. end
  109. return XmlParser
  110. end