[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: XML
- From: Roberto Ierusalimschy <roberto@...>
- Date: Wed, 11 Apr 2001 10:43:02 -0300
> Anyone written an XML parser for Lua?
I have this basic skeleton that parses the "main" part of an XML string (it
does not handle meta-data like "<?" and "<!"...).
-- Roberto
function parseargs (s)
local arg = {}
gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a)
%arg[w] = a
end)
return arg
end
function collect (s)
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 not ni then break end
local text = strsub(s, i, ni-1)
if not strfind(text, "^%s*$") then
tinsert(top, text)
end
if empty == "/" 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
else -- end tag
local toclose = tremove(stack) -- remove top
top = stack[stack.n]
if stack.n < 1 then
error("nothing to close with "..label)
end
if toclose.label ~= label then
error("trying to close "..toclose.label.." with "..label)
end
tinsert(top, toclose)
end
i = j+1
end
local text = strsub(s, i)
if not strfind(text, "^%s*$") then
tinsert(stack[stack.n], text)
end
if stack.n > 1 then
error("unclosed "..stack[stack.n].label)
end
return stack[1]
end
-- example
x = collect[[
<methodCall kind="xuxu">
<methodName>examples.<em>getStateName</em></methodName>
<params>
<param>
<value><i4>41</i4></value>
</param>
</params>
</methodCall>
]]