mod_s2s: Remove compat with namespace issue from Prosody pre-0.6.2
[prosody.git] / util / xml.lua
1
2 local st = require "util.stanza";
3 local lxp = require "lxp";
4
5 local _ENV = nil;
6
7 local parse_xml = (function()
8         local ns_prefixes = {
9                 ["http://www.w3.org/XML/1998/namespace"] = "xml";
10         };
11         local ns_separator = "\1";
12         local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$";
13         return function(xml)
14                 --luacheck: ignore 212/self
15                 local handler = {};
16                 local stanza = st.stanza("root");
17                 function handler:StartElement(tagname, attr)
18                         local curr_ns,name = tagname:match(ns_pattern);
19                         if name == "" then
20                                 curr_ns, name = "", curr_ns;
21                         end
22                         if curr_ns ~= "" then
23                                 attr.xmlns = curr_ns;
24                         end
25                         for i=1,#attr do
26                                 local k = attr[i];
27                                 attr[i] = nil;
28                                 local ns, nm = k:match(ns_pattern);
29                                 if nm ~= "" then
30                                         ns = ns_prefixes[ns];
31                                         if ns then
32                                                 attr[ns..":"..nm] = attr[k];
33                                                 attr[k] = nil;
34                                         end
35                                 end
36                         end
37                         stanza:tag(name, attr);
38                 end
39                 function handler:CharacterData(data)
40                         stanza:text(data);
41                 end
42                 function handler:EndElement()
43                         stanza:up();
44                 end
45                 local parser = lxp.new(handler, "\1");
46                 local ok, err, line, col = parser:parse(xml);
47                 if ok then ok, err, line, col = parser:parse(); end
48                 --parser:close();
49                 if ok then
50                         return stanza.tags[1];
51                 else
52                         return ok, err.." (line "..line..", col "..col..")";
53                 end
54         end;
55 end)();
56
57 return {
58         parse = parse_xml;
59 };