util.stanza: Add stanza:find(), a light weight XPath-like method
authorKim Alvefur <zash@zash.se>
Thu, 04 Apr 2013 20:05:35 +0200
changeset 5424 7318527c6dea
parent 5423 4acc1598f391
child 5425 b00812c6daf8
child 5426 1b20095eb230
util.stanza: Add stanza:find(), a light weight XPath-like method
util/stanza.lua
--- a/util/stanza.lua	Thu Apr 04 19:21:47 2013 +0200
+++ b/util/stanza.lua	Thu Apr 04 20:05:35 2013 +0200
@@ -18,6 +18,7 @@
 local ipairs        =        ipairs;
 local type          =          type;
 local s_gsub        =   string.gsub;
+local s_sub         =    string.sub;
 local s_find        =   string.find;
 local os            =            os;
 
@@ -174,6 +175,31 @@
 	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 = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" };