Software /
code /
prosody
Comparison
util/datamapper.lua @ 11476:83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
So the problem is that xmlns is not inherited when building a stanza,
and then :get_child(n, ns) with an explicit namespace does not find that
such child tags.
E.g.
local t = st.stanza("foo", { xmlns = "urn:example:bar" })
:text_tag("hello", "world");
assert(t:get_child("hello", "urn:example:bar"), "This fails");
Meanwhile, during parsing (util.xmppstream or util.xml) child tags do
get the parents xmlns when not overriding them.
Thus, in the above example, if the stanza is passed trough
`t = util.xml.parse(tostring(t))` then the assert succeeds.
This change makes it so that it leaves out the namespace argument to
:get_child when it is the same as the current/parent namespace, which
behaves the same for both built and parsed stanzas.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 23 Mar 2021 19:52:59 +0100 |
parent | 11475:9bd36e871f05 |
child | 11479:377a9eaf7bef |
comparison
equal
deleted
inserted
replaced
11475:9bd36e871f05 | 11476:83e127eb91f9 |
---|---|
27 local function unpack_propschema(propschema, propname, current_ns) | 27 local function unpack_propschema(propschema, propname, current_ns) |
28 | 28 |
29 local proptype = "string" | 29 local proptype = "string" |
30 local value_where = propname and "in_text_tag" or "in_text" | 30 local value_where = propname and "in_text_tag" or "in_text" |
31 local name = propname | 31 local name = propname |
32 local namespace = current_ns | 32 local namespace |
33 local prefix | 33 local prefix |
34 local single_attribute | 34 local single_attribute |
35 local enums | 35 local enums |
36 | 36 |
37 if type(propschema) == "table" then | 37 if type(propschema) == "table" then |
48 local xml = propschema.xml | 48 local xml = propschema.xml |
49 if xml then | 49 if xml then |
50 if xml.name then | 50 if xml.name then |
51 name = xml.name | 51 name = xml.name |
52 end | 52 end |
53 if xml.namespace then | 53 if xml.namespace and xml.namespace ~= current_ns then |
54 namespace = xml.namespace | 54 namespace = xml.namespace |
55 end | 55 end |
56 if xml.prefix then | 56 if xml.prefix then |
57 prefix = xml.prefix | 57 prefix = xml.prefix |
58 end | 58 end |
103 end | 103 end |
104 elseif value_where == "in_attribute" then | 104 elseif value_where == "in_attribute" then |
105 local attr = name | 105 local attr = name |
106 if prefix then | 106 if prefix then |
107 attr = prefix .. ":" .. name | 107 attr = prefix .. ":" .. name |
108 elseif namespace ~= s.attr.xmlns then | 108 elseif namespace and namespace ~= s.attr.xmlns then |
109 attr = namespace .. "\1" .. name | 109 attr = namespace .. "\1" .. name |
110 end | 110 end |
111 return s.attr[attr] | 111 return s.attr[attr] |
112 | 112 |
113 elseif value_where == "in_text" then | 113 elseif value_where == "in_text" then |
216 local function unparse_property(out, v, proptype, propschema, value_where, name, namespace, current_ns, prefix, single_attribute) | 216 local function unparse_property(out, v, proptype, propschema, value_where, name, namespace, current_ns, prefix, single_attribute) |
217 if value_where == "in_attribute" then | 217 if value_where == "in_attribute" then |
218 local attr = name | 218 local attr = name |
219 if prefix then | 219 if prefix then |
220 attr = prefix .. ":" .. name | 220 attr = prefix .. ":" .. name |
221 elseif namespace ~= current_ns then | 221 elseif namespace and namespace ~= current_ns then |
222 attr = namespace .. "\1" .. name | 222 attr = namespace .. "\1" .. name |
223 end | 223 end |
224 | 224 |
225 out.attr[attr] = toxmlstring(proptype, v) | 225 out.attr[attr] = toxmlstring(proptype, v) |
226 elseif value_where == "in_text" then | 226 elseif value_where == "in_text" then |
227 out:text(toxmlstring(proptype, v)) | 227 out:text(toxmlstring(proptype, v)) |
228 elseif value_where == "in_single_attribute" then | 228 elseif value_where == "in_single_attribute" then |
229 assert(single_attribute) | 229 assert(single_attribute) |
230 local propattr = {} | 230 local propattr = {} |
231 | 231 |
232 if namespace ~= current_ns then | 232 if namespace and namespace ~= current_ns then |
233 propattr.xmlns = namespace | 233 propattr.xmlns = namespace |
234 end | 234 end |
235 | 235 |
236 propattr[single_attribute] = toxmlstring(proptype, v) | 236 propattr[single_attribute] = toxmlstring(proptype, v) |
237 out:tag(name, propattr):up(); | 237 out:tag(name, propattr):up(); |