1 |
1 |
2 local st = require "util.stanza"; |
2 local stanza_mt = require "util.stanza".stanza_mt; |
3 local lxp = require "lxp"; |
|
4 local setmetatable = setmetatable; |
3 local setmetatable = setmetatable; |
5 local pairs = pairs; |
4 local pairs = pairs; |
6 local ipairs = ipairs; |
5 local ipairs = ipairs; |
7 local error = error; |
6 local error = error; |
8 local loadstring = loadstring; |
7 local loadstring = loadstring; |
9 local debug = debug; |
8 local debug = debug; |
10 local t_remove = table.remove; |
9 local t_remove = table.remove; |
|
10 local parse_xml = require "util.xml".parse; |
11 |
11 |
12 module("template") |
12 module("template") |
13 |
|
14 local parse_xml = (function() |
|
15 local ns_prefixes = { |
|
16 ["http://www.w3.org/XML/1998/namespace"] = "xml"; |
|
17 }; |
|
18 local ns_separator = "\1"; |
|
19 local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$"; |
|
20 return function(xml) |
|
21 local handler = {}; |
|
22 local stanza = st.stanza("root"); |
|
23 function handler:StartElement(tagname, attr) |
|
24 local curr_ns,name = tagname:match(ns_pattern); |
|
25 if name == "" then |
|
26 curr_ns, name = "", curr_ns; |
|
27 end |
|
28 if curr_ns ~= "" then |
|
29 attr.xmlns = curr_ns; |
|
30 end |
|
31 for i=1,#attr do |
|
32 local k = attr[i]; |
|
33 attr[i] = nil; |
|
34 local ns, nm = k:match(ns_pattern); |
|
35 if nm ~= "" then |
|
36 ns = ns_prefixes[ns]; |
|
37 if ns then |
|
38 attr[ns..":"..nm] = attr[k]; |
|
39 attr[k] = nil; |
|
40 end |
|
41 end |
|
42 end |
|
43 stanza:tag(name, attr); |
|
44 end |
|
45 function handler:CharacterData(data) |
|
46 stanza:text(data); |
|
47 end |
|
48 function handler:EndElement(tagname) |
|
49 stanza:up(); |
|
50 end |
|
51 local parser = lxp.new(handler, "\1"); |
|
52 local ok, err, line, col = parser:parse(xml); |
|
53 if ok then ok, err, line, col = parser:parse(); end |
|
54 --parser:close(); |
|
55 if ok then |
|
56 return stanza.tags[1]; |
|
57 else |
|
58 return ok, err.." (line "..line..", col "..col..")"; |
|
59 end |
|
60 end; |
|
61 end)(); |
|
62 |
13 |
63 local function trim_xml(stanza) |
14 local function trim_xml(stanza) |
64 for i=#stanza,1,-1 do |
15 for i=#stanza,1,-1 do |
65 local child = stanza[i]; |
16 local child = stanza[i]; |
66 if child.name then |
17 if child.name then |
111 lookup[n] = s; |
62 lookup[n] = s; |
112 lookup[stanza] = "_"..n; |
63 lookup[stanza] = "_"..n; |
113 end |
64 end |
114 return lookup[stanza]; |
65 return lookup[stanza]; |
115 end |
66 end |
116 local stanza_mt = st.stanza_mt; |
|
117 local function create_cloner(stanza, chunkname) |
67 local function create_cloner(stanza, chunkname) |
118 local lookup = {}; |
68 local lookup = {}; |
119 local name = create_clone_string(stanza, lookup, ""); |
69 local name = create_clone_string(stanza, lookup, ""); |
120 local f = "local setmetatable,stanza_mt=...;return function(data)"; |
70 local f = "local setmetatable,stanza_mt=...;return function(data)"; |
121 for i=1,#lookup do |
71 for i=1,#lookup do |