Stary2001

xml

Jan 3rd, 2013
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.46 KB | None | 0 0
  1. -----------------------------------------------------------------------------------------
  2. -- LUA only XmlParser from Alexander Makeev
  3. -----------------------------------------------------------------------------------------
  4. XmlParser = {};
  5.  
  6. function XmlParser:ToXmlString(value)
  7. value = string.gsub (value, "&", "&"); -- '&' -> "&"
  8. value = string.gsub (value, "<", "&lt;"); -- '<' -> "&lt;"
  9. value = string.gsub (value, ">", "&gt;"); -- '>' -> "&gt;"
  10. --value = string.gsub (value, "'", "&apos;"); -- '\'' -> "&apos;"
  11. value = string.gsub (value, "\"", "&quot;"); -- '"' -> "&quot;"
  12. -- replace non printable char -> "&#xD;"
  13. value = string.gsub(value, "([^%w%&%;%p%\t% ])",
  14. function (c)
  15. return string.format("&#x%X;", string.byte(c))
  16. --return string.format("&#x%02X;", string.byte(c))
  17. --return string.format("&#%02d;", string.byte(c))
  18. end);
  19. return value;
  20. end
  21.  
  22. function XmlParser:FromXmlString(value)
  23. value = string.gsub(value, "&#x([%x]+)%;",
  24. function(h)
  25. return string.char(tonumber(h,16))
  26. end);
  27. value = string.gsub(value, "&#([0-9]+)%;",
  28. function(h)
  29. return string.char(tonumber(h,10))
  30. end);
  31. value = string.gsub (value, "&quot;", "\"");
  32. value = string.gsub (value, "&apos;", "'");
  33. value = string.gsub (value, "&gt;", ">");
  34. value = string.gsub (value, "&lt;", "<");
  35. value = string.gsub (value, "&amp;", "&");
  36. return value;
  37. end
  38.  
  39. function XmlParser:ParseArgs(s)
  40. local arg = {}
  41. string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a)
  42. arg[w] = self:FromXmlString(a);
  43. end)
  44. return arg
  45. end
  46.  
  47. function XmlParser:ParseXmlText(xmlText)
  48. local stack = {}
  49. local top = {Name=nil,Value=nil,Attributes={},ChildNodes={}}
  50. table.insert(stack, top)
  51. local ni,c,label,xarg, empty
  52. local i, j = 1, 1
  53. while true do
  54. ni,j,c,label,xarg, empty = string.find(xmlText, "<(%/?)([%w:]+)(.-)(%/?)>", i)
  55. if not ni then break end
  56. local text = string.sub(xmlText, i, ni-1);
  57. if not string.find(text, "^%s*$") then
  58. top.Value=(top.Value or "")..self:FromXmlString(text);
  59. end
  60. if empty == "/" then -- empty element tag
  61. table.insert(top.ChildNodes, {Name=label,Value=nil,Attributes=self:ParseArgs(xarg),ChildNodes={}})
  62. elseif c == "" then -- start tag
  63. top = {Name=label, Value=nil, Attributes=self:ParseArgs(xarg), ChildNodes={}}
  64. table.insert(stack, top) -- new level
  65. --log("openTag ="..top.Name);
  66. else -- end tag
  67. local toclose = table.remove(stack) -- remove top
  68. --log("closeTag="..toclose.Name);
  69. top = stack[#stack]
  70. if #stack < 1 then
  71. error("XmlParser: nothing to close with "..label)
  72. end
  73. if toclose.Name ~= label then
  74. error("XmlParser: trying to close "..toclose.Name.." with "..label)
  75. end
  76. table.insert(top.ChildNodes, toclose)
  77. end
  78. i = j+1
  79. end
  80. local text = string.sub(xmlText, i);
  81. if not string.find(text, "^%s*$") then
  82. stack[#stack].Value=(stack[#stack].Value or "")..self:FromXmlString(text);
  83. end
  84. if #stack > 1 then
  85. error("XmlParser: unclosed "..stack[stack.n].Name)
  86. end
  87. return stack[1].ChildNodes[1];
  88. end
  89.  
  90. function XmlParser:ParseXmlFile(xmlFileName)
  91. local hFile,err = io.open(xmlFileName,"r");
  92. if (not err) then
  93. local xmlText=hFile:read("*a"); -- read file content
  94. io.close(hFile);
  95. return self:ParseXmlText(xmlText),nil;
  96. else
  97. return nil,err;
  98. end
  99. end
Advertisement
Add Comment
Please, Sign In to add comment