util/template.lua
changeset 5214 1430c6f36621
parent 4495 c0f5c78cb817
child 6780 5de6b93d0190
equal deleted inserted replaced
5213:cc487921746b 5214:1430c6f36621
     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