X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=util%2Fstanza.lua;h=7c21421083d57daafbcf2ad807c3d7b7166c36a5;hb=84c934632367eac822fb6af2663032b67fd0a596;hp=5c430f1d887ce0833ebff89505145f3a30cad97a;hpb=cde1d850e6137e9b59e728aa805f2c3bae754c3c;p=prosody.git diff --git a/util/stanza.lua b/util/stanza.lua index 5c430f1d..7c214210 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -18,6 +18,7 @@ local pairs = pairs; local ipairs = ipairs; local type = type; local s_gsub = string.gsub; +local s_sub = string.sub; local s_find = string.find; local os = os; @@ -153,7 +154,7 @@ function stanza_mt:maptags(callback) local n_children, n_tags = #self, #tags; local i = 1; - while curr_tag <= n_tags do + while curr_tag <= n_tags and n_tags > 0 do if self[i] == tags[curr_tag] then local ret = callback(self[i]); if ret == nil then @@ -161,17 +162,44 @@ function stanza_mt:maptags(callback) t_remove(tags, curr_tag); n_children = n_children - 1; n_tags = n_tags - 1; + i = i - 1; + curr_tag = curr_tag - 1; else self[i] = ret; - tags[i] = ret; + tags[curr_tag] = ret; end - i = i + 1; curr_tag = curr_tag + 1; end + i = i + 1; end return self; end +function stanza_mt:find(path) + local pos = 1; + local len = #path + 1; + + repeat + local xmlns, name, text; + local char = s_sub(path, pos, pos); + if char == "@" then + return self.attr[s_sub(path, pos + 1)]; + elseif char == "{" then + xmlns, pos = s_match(path, "^([^}]+)}()", pos + 1); + end + name, text, pos = s_match(path, "^([^@/#]*)([/#]?)()", pos); + name = name ~= "" and name or nil; + if pos == len then + if text == "#" then + return self:get_child_text(name, xmlns); + end + return self:get_child(name, xmlns); + end + self = self:get_child(name, xmlns); + until not self +end + + local xml_escape do local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; @@ -237,7 +265,7 @@ function stanza_mt.get_error(stanza) end type = error_tag.attr.type; - for child in error_tag:childtags() do + for _, child in ipairs(error_tag.tags) do if child.attr.xmlns == xmlns_stanzas then if not text and child.name == "text" then text = child:get_text();