Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -----------------------------------------------------------------------------------------
- -- LUA only XmlParser from Alexander Makeev
- -----------------------------------------------------------------------------------------
- XmlParser = {};
- function XmlParser:ToXmlString(value)
- value = string.gsub (value, "&", "&"); -- '&' -> "&"
- value = string.gsub (value, "<", "<"); -- '<' -> "<"
- value = string.gsub (value, ">", ">"); -- '>' -> ">"
- --value = string.gsub (value, "'", "'"); -- '\'' -> "'"
- value = string.gsub (value, "\"", """); -- '"' -> """
- -- replace non printable char -> "
"
- value = string.gsub(value, "([^%w%&%;%p%\t% ])",
- function (c)
- return string.format("&#x%X;", string.byte(c))
- --return string.format("&#x%02X;", string.byte(c))
- --return string.format("&#%02d;", string.byte(c))
- end);
- return value;
- end
- function XmlParser:FromXmlString(value)
- value = string.gsub(value, "&#x([%x]+)%;",
- function(h)
- return string.char(tonumber(h,16))
- end);
- value = string.gsub(value, "&#([0-9]+)%;",
- function(h)
- return string.char(tonumber(h,10))
- end);
- value = string.gsub (value, """, "\"");
- value = string.gsub (value, "'", "'");
- value = string.gsub (value, ">", ">");
- value = string.gsub (value, "<", "<");
- value = string.gsub (value, "&", "&");
- return value;
- end
- function XmlParser:ParseArgs(s)
- local arg = {}
- string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a)
- arg[w] = self:FromXmlString(a);
- end)
- return arg
- end
- function XmlParser:ParseXmlText(xmlText)
- local stack = {}
- local top = {Name=nil,Value=nil,Attributes={},ChildNodes={}}
- 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(xmlText, "<(%/?)([%w:]+)(.-)(%/?)>", i)
- if not ni then break end
- local text = string.sub(xmlText, i, ni-1);
- if not string.find(text, "^%s*$") then
- top.Value=(top.Value or "")..self:FromXmlString(text);
- end
- if empty == "/" then -- empty element tag
- table.insert(top.ChildNodes, {Name=label,Value=nil,Attributes=self:ParseArgs(xarg),ChildNodes={}})
- elseif c == "" then -- start tag
- top = {Name=label, Value=nil, Attributes=self:ParseArgs(xarg), ChildNodes={}}
- table.insert(stack, top) -- new level
- --log("openTag ="..top.Name);
- else -- end tag
- local toclose = table.remove(stack) -- remove top
- --log("closeTag="..toclose.Name);
- top = stack[#stack]
- if #stack < 1 then
- error("XmlParser: nothing to close with "..label)
- end
- if toclose.Name ~= label then
- error("XmlParser: trying to close "..toclose.Name.." with "..label)
- end
- table.insert(top.ChildNodes, toclose)
- end
- i = j+1
- end
- local text = string.sub(xmlText, i);
- if not string.find(text, "^%s*$") then
- stack[#stack].Value=(stack[#stack].Value or "")..self:FromXmlString(text);
- end
- if #stack > 1 then
- error("XmlParser: unclosed "..stack[stack.n].Name)
- end
- return stack[1].ChildNodes[1];
- end
- function XmlParser:ParseXmlFile(xmlFileName)
- local hFile,err = io.open(xmlFileName,"r");
- if (not err) then
- local xmlText=hFile:read("*a"); -- read file content
- io.close(hFile);
- return self:ParseXmlText(xmlText),nil;
- else
- return nil,err;
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment