src/lxp/lom.lua

changeset 36
4a61f00ee916
parent 10
e981a82571cf
equal deleted inserted replaced
35:d2d0bc06eac2 36:4a61f00ee916
1 -- See Copyright Notice in license.html 1 -- See Copyright Notice in license.html
2 -- $Id: lom.lua,v 1.6 2005/06/09 19:18:40 tuler Exp $
3 2
4 local lxp = require "lxp" 3 local lxp = require "lxp"
5 4
5 local table = require"table"
6 local tinsert, tremove = table.insert, table.remove 6 local tinsert, tremove = table.insert, table.remove
7 local assert, type, print = assert, type, print 7 local assert, pairs, type = assert, pairs, type
8 8
9 9
10 -- auxiliary functions -------------------------------------------------------
10 local function starttag (p, tag, attr) 11 local function starttag (p, tag, attr)
11 local stack = p:getcallbacks().stack 12 local stack = p:getcallbacks().stack
12 local newelement = {tag = tag, attr = attr} 13 local newelement = {tag = tag, attr = attr}
13 tinsert(stack, newelement) 14 tinsert(stack, newelement)
14 end 15 end
30 else 31 else
31 tinsert(element, txt) 32 tinsert(element, txt)
32 end 33 end
33 end 34 end
34 35
36 -- main function -------------------------------------------------------------
35 local function parse (o) 37 local function parse (o)
36 local c = { StartElement = starttag, 38 local c = { StartElement = starttag,
37 EndElement = endtag, 39 EndElement = endtag,
38 CharacterData = text, 40 CharacterData = text,
39 _nonstrict = true, 41 _nonstrict = true,
40 stack = {{}} 42 stack = {{}}
41 } 43 }
42 local p = lxp.new(c) 44 local p = lxp.new(c)
43 local status, err 45 local to = type(o)
44 if type(o) == "string" then 46 if to == "string" then
45 status, err = p:parse(o) 47 local status, err, line, col, pos = p:parse(o)
46 if not status then return nil, err end 48 if not status then return nil, err, line, col, pos end
47 else 49 else
48 for l in pairs(o) do 50 local iter, state, init
49 status, err = p:parse(l) 51 if to == "table" then
50 if not status then return nil, err end 52 iter, state, init = pairs(o)
51 end 53 elseif to == "function" then
52 end 54 iter = o
53 status, err = p:parse() 55 elseif to == "userdata" and o.read then
54 if not status then return nil, err end 56 iter, state = o.read, o
55 p:close() 57 else
56 return c.stack[1][1] 58 error ("Bad argument #1 to parse: expected a string, a table, a function or a file, but got "..to, 2)
59 end
60 for l in iter, state, init do
61 local status, err, line, col, pos = p:parse(l)
62 if not status then return nil, err, line, col, pos end
63 end
64 end
65 local status, err, line, col, pos = p:parse() -- close document
66 if not status then return nil, err, line, col, pos end
67 p:close()
68 return c.stack[1][1]
57 end 69 end
58 70
59 return { parse = parse } 71 -- utility functions ---------------------------------------------------------
72 local function find_elem (self, tag)
73 if self.tag == tag then
74 return self
75 end
76 for i = 1, #self do
77 local v = self[i]
78 if type(v) == "table" then
79 local found = find_elem (v, tag)
80 if found then
81 return found
82 end
83 end
84 end
85 return nil
86 end
87
88 local function list_children (self, tag)
89 local i = 0
90 return function ()
91 i = i+1
92 local v = self[i]
93 while v do
94 if type (v) == "table" and (tag == nil or tag == v.tag) then
95 return v
96 end
97 i = i+1
98 v = self[i]
99 end
100 return nil
101 end
102 end
103
104 return {
105 find_elem = find_elem,
106 list_children = list_children,
107 parse = parse,
108 }

mercurial