summaryrefslogtreecommitdiff
path: root/Data/Libraries/Penlight/examples/testxml.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Data/Libraries/Penlight/examples/testxml.lua')
-rw-r--r--Data/Libraries/Penlight/examples/testxml.lua83
1 files changed, 83 insertions, 0 deletions
diff --git a/Data/Libraries/Penlight/examples/testxml.lua b/Data/Libraries/Penlight/examples/testxml.lua
new file mode 100644
index 0000000..2528020
--- /dev/null
+++ b/Data/Libraries/Penlight/examples/testxml.lua
@@ -0,0 +1,83 @@
+-- an example showing 'pl.lexer' doing some serious work.
+-- The resulting Lua table is in the same LOM format used by luaexpat.
+-- This is (clearly) not a professional XML parser, so don't use it
+-- on your homework!
+
+local lexer = require 'pl.lexer'
+local pretty = require 'pl.pretty'
+
+local append = table.insert
+local skipws,expecting = lexer.skipws,lexer.expecting
+
+local function parse_element (tok,tag)
+ local tbl,t,v,attrib
+ tbl = {}
+ tbl.tag = tag -- LOM 'tag' is the element tag
+ t,v = skipws(tok)
+ while v ~= '/' and v ~= '>' do
+ if t ~= 'iden' then error('expecting attribute identifier') end
+ attrib = v
+ expecting(tok,'=')
+ v = expecting(tok,'string')
+ -- LOM: 'attr' subtable contains attrib/value pairs and an ordered list of attribs
+ if not tbl.attr then tbl.attr = {} end
+ tbl.attr[attrib] = v
+ append(tbl.attr,attrib)
+ t,v = skipws(tok)
+ end
+ if v == '/' then
+ expecting(tok,'>')
+ return tbl
+ end
+ -- pick up element data
+ t,v = tok()
+ while true do
+ if t == '<' then
+ t,v = skipws(tok)
+ if t == '/' then -- element end tag
+ t,v = tok()
+ if t == '>' then return tbl end
+ if t == 'iden' and v == tag then
+ if tok() == '>' then return tbl end
+ end
+ error('expecting end tag '..tag)
+ else
+ append(tbl,parse_element(tok,v)) -- LOM: child elements added to table
+ t,v = skipws(tok)
+ end
+ else
+ append(tbl,v) -- LOM: text added to table
+ t,v = skipws(tok)
+ end
+ end
+end
+
+local function parse_xml (tok)
+ local t = skipws(tok)
+ local v
+ while t == '<' do
+ t,v = tok()
+ if t == '?' or t == '!' then
+ -- skip meta stuff and commentary
+ repeat t = tok() until t == '>'
+ t = expecting(tok,'<')
+ else
+ return parse_element(tok,v)
+ end
+ end
+end
+
+local s = [[
+<?xml version="1.0" encoding="UTF-8"?>
+<sensor name="closure-meter-2" id="7D7D0600006F0D00" loc="100,100,0" device="closure-meter" init="true">
+<detector name="closure-meter" phenomenon="closure" units="mm" id="1"
+ vmin="0" vmax="5000" device="closure-meter" calib="0,0;5000,5000"
+ sampling_interval="25000" measurement_interval="600000"
+/>
+</sensor>
+]]
+
+local tok = lexer.scan(s,nil,{space=false},{string=true})
+local res = parse_xml(tok)
+print(pretty.write(res))
+