forked from Phrogz/SLAXML
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslaxdom.lua
49 lines (49 loc) · 2.06 KB
/
slaxdom.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
-- Optional parser that creates a flat DOM from parsing
local SLAXML = require 'slaxml'
function SLAXML:dom(xml,opts)
if not opts then opts={} end
local rich = not opts.simple
local push, pop = table.insert, table.remove
local stack = {}
local doc = { type="document", name="#doc", kids={} }
local current = doc
local builder = SLAXML:parser{
startElement = function(name,nsURI)
local el = { type="element", name=name, kids={}, el=rich and {} or nil, attr={}, nsURI=nsURI, parent=rich and current or nil }
if current==doc then
if doc.root then error(("Encountered element '%s' when the document already has a root '%s' element"):format(name,doc.root.name)) end
doc.root = el
end
push(current.kids,el)
if current.el then push(current.el,el) end
current = el
push(stack,el)
end,
attribute = function(name,value,nsURI)
if not current or current.type~="element" then error(("Encountered an attribute %s=%s but I wasn't inside an element"):format(name,value)) end
local attr = {type='attribute',name=name,nsURI=nsURI,value=value,parent=rich and current or nil}
if rich then current.attr[name] = value end
push(current.attr,attr)
end,
closeElement = function(name)
if current.name~=name or current.type~="element" then error(("Received a close element notification for '%s' but was inside a '%s' %s"):format(name,current.name,current.type)) end
pop(stack)
current = stack[#stack]
end,
text = function(value)
if current.type~='document' then
if current.type~="element" then error(("Received a text notification '%s' but was inside a %s"):format(value,current.type)) end
push(current.kids,{type='text',name='#text',value=value,parent=rich and current or nil})
end
end,
comment = function(value)
push(current.kids,{type='comment',name='#comment',value=value,parent=rich and current or nil})
end,
pi = function(name,value)
push(current.kids,{type='pi',name=name,value=value,parent=rich and current or nil})
end
}
builder:parse(xml,opts)
return doc
end
return SLAXML