util/xml.lua
changeset 7242 c9af793b2d8f
parent 6981 30c96a5db360
child 8558 4f0f5b49bb03
equal deleted inserted replaced
7241:7df4e385b248 7242:c9af793b2d8f
     1 
     1 
     2 local st = require "util.stanza";
     2 local st = require "util.stanza";
     3 local lxp = require "lxp";
     3 local lxp = require "lxp";
       
     4 local t_insert = table.insert;
       
     5 local t_remove = table.remove;
     4 
     6 
     5 local _ENV = nil;
     7 local _ENV = nil;
     6 
     8 
     7 local parse_xml = (function()
     9 local parse_xml = (function()
     8 	local ns_prefixes = {
    10 	local ns_prefixes = {
    12 	local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$";
    14 	local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$";
    13 	return function(xml)
    15 	return function(xml)
    14 		--luacheck: ignore 212/self
    16 		--luacheck: ignore 212/self
    15 		local handler = {};
    17 		local handler = {};
    16 		local stanza = st.stanza("root");
    18 		local stanza = st.stanza("root");
    17 		local namespaces = {}
    19 		local namespaces = {};
       
    20 		local prefixes = {};
    18 		function handler:StartNamespaceDecl(prefix, url)
    21 		function handler:StartNamespaceDecl(prefix, url)
    19 			if prefix ~= nil then
    22 			if prefix ~= nil then
    20 				namespaces[prefix] = url
    23 				t_insert(namespaces, url);
       
    24 				t_insert(prefixes, prefix);
    21 			end
    25 			end
    22 		end
    26 		end
    23 		function handler:EndNamespaceDecl(prefix)
    27 		function handler:EndNamespaceDecl(prefix)
    24 			if prefix ~= nil then
    28 			if prefix ~= nil then
    25 				namespaces[prefix] = nil
    29 				-- we depend on each StartNamespaceDecl having a paired EndNamespaceDecl
       
    30 				t_remove(namespaces);
       
    31 				t_remove(prefixes);
    26 			end
    32 			end
    27 		end
    33 		end
    28 		function handler:StartElement(tagname, attr)
    34 		function handler:StartElement(tagname, attr)
    29 			local curr_ns,name = tagname:match(ns_pattern);
    35 			local curr_ns,name = tagname:match(ns_pattern);
    30 			if name == "" then
    36 			if name == "" then
    44 						attr[k] = nil;
    50 						attr[k] = nil;
    45 					end
    51 					end
    46 				end
    52 				end
    47 			end
    53 			end
    48 			local n = {}
    54 			local n = {}
    49 			for prefix, url in pairs(namespaces) do
    55 			for i=1,#namespaces do
    50 				n[prefix] = url
    56 				n[prefixes[i]] = namespaces[i];
    51 			end
    57 			end
    52 			stanza:tag(name, attr, n);
    58 			stanza:tag(name, attr, n);
    53 		end
    59 		end
    54 		function handler:CharacterData(data)
    60 		function handler:CharacterData(data)
    55 			stanza:text(data);
    61 			stanza:text(data);