Comparison

util/stanza.lua @ 9924:5a2e53bef031

util.stanza: Fix :top_tag() handling of namespaced attributes
author Matthew Wild <mwild1@gmail.com>
date Mon, 25 Mar 2019 14:37:43 +0000
parent 9732:51583ea2b4fd
child 10116:4807535b8673
comparison
equal deleted inserted replaced
9923:e83dfcdeab59 9924:5a2e53bef031
268 end 268 end
269 self = self:get_child(name, xmlns); 269 self = self:get_child(name, xmlns);
270 until not self 270 until not self
271 end 271 end
272 272
273 local function _clone(stanza, only_top)
274 local attr, tags = {}, {};
275 for k,v in pairs(stanza.attr) do attr[k] = v; end
276 local old_namespaces, namespaces = stanza.namespaces;
277 if old_namespaces then
278 namespaces = {};
279 for k,v in pairs(old_namespaces) do namespaces[k] = v; end
280 end
281 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags };
282 if not only_top then
283 for i=1,#stanza do
284 local child = stanza[i];
285 if child.name then
286 child = _clone(child);
287 t_insert(tags, child);
288 end
289 t_insert(new, child);
290 end
291 end
292 return setmetatable(new, stanza_mt);
293 end
294
295 local function clone(stanza, only_top)
296 if not is_stanza(stanza) then
297 error("bad argument to clone: expected stanza, got "..type(stanza));
298 end
299 return _clone(stanza, only_top);
300 end
273 301
274 local escape_table = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" }; 302 local escape_table = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" };
275 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end 303 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end
276 304
277 local function _dostring(t, buf, self, _xml_escape, parentns) 305 local function _dostring(t, buf, self, _xml_escape, parentns)
308 _dostring(t, buf, _dostring, xml_escape, nil); 336 _dostring(t, buf, _dostring, xml_escape, nil);
309 return t_concat(buf); 337 return t_concat(buf);
310 end 338 end
311 339
312 function stanza_mt.top_tag(t) 340 function stanza_mt.top_tag(t)
313 local attr_string = ""; 341 local top_tag_clone = clone(t, true);
314 if t.attr then 342 return tostring(top_tag_clone):sub(1,-3)..">";
315 for k, v in pairs(t.attr) do if type(k) == "string" then attr_string = attr_string .. s_format(" %s='%s'", k, xml_escape(tostring(v))); end end
316 end
317 return s_format("<%s%s>", t.name, attr_string);
318 end 343 end
319 344
320 function stanza_mt.get_text(t) 345 function stanza_mt.get_text(t)
321 if #t.tags == 0 then 346 if #t.tags == 0 then
322 return t_concat(t); 347 return t_concat(t);
384 stanza:add_direct_child(child); 409 stanza:add_direct_child(child);
385 end 410 end
386 end 411 end
387 return stanza; 412 return stanza;
388 end 413 end
389 end
390
391 local function _clone(stanza)
392 local attr, tags = {}, {};
393 for k,v in pairs(stanza.attr) do attr[k] = v; end
394 local old_namespaces, namespaces = stanza.namespaces;
395 if old_namespaces then
396 namespaces = {};
397 for k,v in pairs(old_namespaces) do namespaces[k] = v; end
398 end
399 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags };
400 for i=1,#stanza do
401 local child = stanza[i];
402 if child.name then
403 child = _clone(child);
404 t_insert(tags, child);
405 end
406 t_insert(new, child);
407 end
408 return setmetatable(new, stanza_mt);
409 end
410
411 local function clone(stanza)
412 if not is_stanza(stanza) then
413 error("bad argument to clone: expected stanza, got "..type(stanza));
414 end
415 return _clone(stanza);
416 end 414 end
417 415
418 local function message(attr, body) 416 local function message(attr, body)
419 if not body then 417 if not body then
420 return new_stanza("message", attr); 418 return new_stanza("message", attr);