114 if v then return v; end |
115 if v then return v; end |
115 end, self.tags[1], i; |
116 end, self.tags[1], i; |
116 |
117 |
117 end |
118 end |
118 |
119 |
119 do |
120 local xml_escape = (function() |
120 local xml_entities = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; |
121 local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; |
121 function xml_escape(s) return s_gsub(s, "['&<>\"]", xml_entities); end |
122 return function(str) return (s_gsub(str, "['&<>\"]", escape_table)); end |
122 end |
123 end)(); |
123 |
124 local function _dostring(t, buf, self, xml_escape) |
124 local xml_escape = xml_escape; |
|
125 |
|
126 local function dostring(t, buf, self, xml_escape) |
|
127 local nsid, ns, attrk = 0; |
125 local nsid, ns, attrk = 0; |
128 t_insert(buf, "<"); |
126 t_insert(buf, "<"..t.name); |
129 t_insert(buf, t.name); |
127 for k, v in pairs(t.attr) do |
130 for k, v in pairs(t.attr) do if type(k) == "string" then |
|
131 t_insert(buf, " "); |
|
132 ns, attrk = s_match(k, "^([^|]+)|(.+)$"); |
128 ns, attrk = s_match(k, "^([^|]+)|(.+)$"); |
133 if ns then |
129 if ns then |
134 nsid = (nsid or -1) + 1; |
130 nsid = nsid + 1; |
135 t_insert(buf, "xmlns:ns"..nsid); |
131 t_insert(buf, " xmlns:ns"..nsid.."='"..xml_escape(ns).."' ".."ns"..nsid..":"..attrk.."='"..xml_escape(v).."'"); |
136 t_insert(buf, "='"); |
|
137 t_insert(buf, (xml_escape(tostring(ns)))); |
|
138 t_insert(buf, "' "); |
|
139 t_insert(buf, "ns"..nsid..":"..attrk); |
|
140 else |
132 else |
141 t_insert(buf, k); |
133 t_insert(buf, " "..k.."='"..xml_escape(v).."'"); |
142 end |
134 end |
143 t_insert(buf, "='"); |
135 end |
144 t_insert(buf, (xml_escape(tostring(v)))); |
|
145 t_insert(buf, "'"); |
|
146 end end |
|
147 t_insert(buf, ">"); |
136 t_insert(buf, ">"); |
148 for n, child in ipairs(t) do |
137 for n=1,#t do |
149 if child.name then |
138 local child = t[n]; |
|
139 if child.name then |
150 self(child, buf, self, xml_escape); |
140 self(child, buf, self, xml_escape); |
151 else |
141 else |
152 t_insert(buf, (xml_escape(child))); |
142 t_insert(buf, xml_escape(child)); |
153 end |
143 end |
154 end |
144 end |
155 t_insert(buf, "</"); |
145 t_insert(buf, "</"..t.name..">"); |
156 t_insert(buf, t.name); |
146 end |
157 t_insert(buf, ">"); |
|
158 end |
|
159 |
|
160 function stanza_mt.__tostring(t) |
147 function stanza_mt.__tostring(t) |
161 local buf = {}; |
148 local buf = {}; |
162 dostring(t, buf, dostring, xml_escape); |
149 _dostring(t, buf, _dostring, xml_escape); |
163 return t_concat(buf); |
150 return t_concat(buf); |
164 end |
151 end |
165 |
|
166 |
152 |
167 function stanza_mt.top_tag(t) |
153 function stanza_mt.top_tag(t) |
168 local attr_string = ""; |
154 local attr_string = ""; |
169 if t.attr then |
155 if t.attr then |
170 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 |
156 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 |