util.stanza, util.xml, util.xmppstream: Add support for tracking defined namespaces...
authorMatthew Wild <mwild1@gmail.com>
Tue, 8 Dec 2015 23:15:42 +0000 (23:15 +0000)
committerMatthew Wild <mwild1@gmail.com>
Tue, 8 Dec 2015 23:15:42 +0000 (23:15 +0000)
util/stanza.lua
util/xml.lua
util/xmppstream.lua

index 90422a0622659eec9f9e81611884c9c6dfa07d47..c682f8333653a9a37e73cdbdf67dedbfe97a76dd 100644 (file)
@@ -40,8 +40,8 @@ local _ENV = nil;
 local stanza_mt = { __type = "stanza" };
 stanza_mt.__index = stanza_mt;
 
-local function stanza(name, attr)
-       local stanza = { name = name, attr = attr or {}, tags = {} };
+local function stanza(name, attr, namespaces)
+       local stanza = { name = name, attr = attr or {}, namespaces = namespaces, tags = {} };
        return setmetatable(stanza, stanza_mt);
 end
 local stanza = stanza;
@@ -54,8 +54,8 @@ function stanza_mt:body(text, attr)
        return self:tag("body", attr):text(text);
 end
 
-function stanza_mt:tag(name, attrs)
-       local s = stanza(name, attrs);
+function stanza_mt:tag(name, attr, namespaces)
+       local s = stanza(name, attr, namespaces);
        local last_add = self.last_add;
        if not last_add then last_add = {}; self.last_add = last_add; end
        (last_add[#last_add] or self):add_direct_child(s);
@@ -333,7 +333,12 @@ end
 local function clone(stanza)
        local attr, tags = {}, {};
        for k,v in pairs(stanza.attr) do attr[k] = v; end
-       local new = { name = stanza.name, attr = attr, tags = tags };
+       local old_namespaces, namespaces = stanza.namespaces;
+       if old_namespaces then
+               namespaces = {};
+               for k,v in pairs(old_namespaces) do namespaces[k] = v; end
+       end
+       local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags };
        for i=1,#stanza do
                local child = stanza[i];
                if child.name then
index 733d821ad7c8b87dc93d7e4a0b3ab2cfa030fd85..9e12f0dff1b6856cf94a798d2291ead3c223fea9 100644 (file)
@@ -14,6 +14,17 @@ local parse_xml = (function()
                --luacheck: ignore 212/self
                local handler = {};
                local stanza = st.stanza("root");
+               local namespaces = {}
+               function handler:StartNamespaceDecl(prefix, url)
+                       if prefix ~= nil then
+                               namespaces[prefix] = url
+                       end
+               end
+               function handler:EndNamespaceDecl(prefix)
+                       if prefix ~= nil then
+                               namespaces[prefix] = nil
+                       end
+               end
                function handler:StartElement(tagname, attr)
                        local curr_ns,name = tagname:match(ns_pattern);
                        if name == "" then
@@ -34,7 +45,11 @@ local parse_xml = (function()
                                        end
                                end
                        end
-                       stanza:tag(name, attr);
+                       local n = {}
+                       for prefix, url in pairs(namespaces) do
+                               n[prefix] = url
+                       end
+                       stanza:tag(name, attr, n);
                end
                function handler:CharacterData(data)
                        stanza:text(data);
index 7be63285dfdb48c8d219cab5190e930ffdaa6b9d..3d97acef1c87fde71187170435f8a3ac2c779707 100644 (file)
@@ -196,6 +196,29 @@ local function new_sax_handlers(session, stream_callbacks, cb_handleprogress)
                end
        end
 
+       if stream_callbacks.track_namespaces then
+               local namespaces = {}
+               function xml_handlers:StartNamespaceDecl(prefix, url)
+                       if prefix ~= nil then
+                               namespaces[prefix] = url
+                       end
+               end
+               function xml_handlers:EndNamespaceDecl(prefix)
+                       if prefix ~= nil then
+                               namespaces[prefix] = nil
+                       end
+               end
+               local old_startelement = xml_handlers.StartElement
+               function xml_handlers:StartElement(tagname, attr)
+                       old_startelement(self, tagname, attr)
+                       local n = {}
+                       for prefix, url in pairs(namespaces) do
+                               n[prefix] = url
+                       end
+                       stanza.namespaces = n
+               end
+       end
+
        local function restricted_handler(parser)
                cb_error(session, "parse-error", "restricted-xml", "Restricted XML, see RFC 6120 section 11.1.");
                if not parser.stop or not parser:stop() then