Comparison

util/datamapper.lua @ 11439:9abcdfdcdb01

util.datamapper: Add support for mapping of elements where only one attribute matters E.g. <feature var='foo'/> in XEP-0030 and some other simple specifications.
author Kim Alvefur <zash@zash.se>
date Sun, 07 Mar 2021 12:48:49 +0100
parent 11438:b7807583de34
child 11451:ee4f2296e7df
comparison
equal deleted inserted replaced
11438:b7807583de34 11439:9abcdfdcdb01
17 local namespace = s.attr.xmlns; 17 local namespace = s.attr.xmlns;
18 local prefix = nil 18 local prefix = nil
19 local is_attribute = false 19 local is_attribute = false
20 local is_text = false 20 local is_text = false
21 local name_is_value = false; 21 local name_is_value = false;
22 local single_attribute
22 23
23 local proptype 24 local proptype
24 if type(propschema) == "table" then 25 if type(propschema) == "table" then
25 proptype = propschema.type 26 proptype = propschema.type
26 elseif type(propschema) == "string" then 27 elseif type(propschema) == "string" then
41 is_attribute = true 42 is_attribute = true
42 elseif propschema.xml.text then 43 elseif propschema.xml.text then
43 is_text = true 44 is_text = true
44 elseif propschema.xml.x_name_is_value then 45 elseif propschema.xml.x_name_is_value then
45 name_is_value = true 46 name_is_value = true
47 elseif propschema.xml.x_single_attribute then
48 single_attribute = propschema.xml.x_single_attribute
46 end 49 end
47 end 50 end
48 51
49 if name_is_value then 52 if name_is_value then
50 local c = s:get_child(nil, namespace); 53 local c = s:get_child(nil, namespace);
75 out[prop] = s:get_text() 78 out[prop] = s:get_text()
76 elseif proptype == "integer" or proptype == "number" then 79 elseif proptype == "integer" or proptype == "number" then
77 out[prop] = tonumber(s:get_text()) 80 out[prop] = tonumber(s:get_text())
78 end 81 end
79 82
83 elseif single_attribute then
84 local c = s:get_child(name, namespace)
85 local a = c and c.attr[single_attribute]
86 if proptype == "string" then
87 out[prop] = a
88 elseif proptype == "integer" or proptype == "number" then
89 out[prop] = tonumber(a)
90 elseif proptype == "boolean" then
91 out[prop] = toboolean(a)
92 end
80 else 93 else
81 94
82 if proptype == "string" then 95 if proptype == "string" then
83 out[prop] = s:get_child_text(name, namespace) 96 out[prop] = s:get_child_text(name, namespace)
84 elseif proptype == "integer" or proptype == "number" then 97 elseif proptype == "integer" or proptype == "number" then
133 local namespace = current_ns 146 local namespace = current_ns
134 local prefix = nil 147 local prefix = nil
135 local is_attribute = false 148 local is_attribute = false
136 local is_text = false 149 local is_text = false
137 local name_is_value = false; 150 local name_is_value = false;
151 local single_attribute
138 152
139 if type(propschema) == "table" and propschema.xml then 153 if type(propschema) == "table" and propschema.xml then
140 154
141 if propschema.xml.name then 155 if propschema.xml.name then
142 name = propschema.xml.name 156 name = propschema.xml.name
153 is_attribute = true 167 is_attribute = true
154 elseif propschema.xml.text then 168 elseif propschema.xml.text then
155 is_text = true 169 is_text = true
156 elseif propschema.xml.x_name_is_value then 170 elseif propschema.xml.x_name_is_value then
157 name_is_value = true 171 name_is_value = true
172 elseif propschema.xml.x_single_attribute then
173 single_attribute = propschema.xml.x_single_attribute
158 end 174 end
159 end 175 end
160 176
161 if is_attribute then 177 if is_attribute then
162 local attr = name 178 local attr = name
177 end 193 end
178 elseif is_text then 194 elseif is_text then
179 if type(v) == "string" then 195 if type(v) == "string" then
180 out:text(v) 196 out:text(v)
181 end 197 end
198 elseif single_attribute then
199 local propattr = {}
200
201 if namespace ~= current_ns then
202 propattr.xmlns = namespace
203 end
204
205 if proptype == "string" and type(v) == "string" then
206 propattr[single_attribute] = v
207 elseif proptype == "number" and type(v) == "number" then
208 propattr[single_attribute] = string.format("%g", v)
209 elseif proptype == "integer" and type(v) == "number" then
210 propattr[single_attribute] = string.format("%d", v)
211 elseif proptype == "boolean" and type(v) == "boolean" then
212 propattr[single_attribute] = v and "1" or "0"
213 end
214 out:tag(name, propattr):up();
215
182 else 216 else
183 local propattr 217 local propattr
184 if namespace ~= current_ns then 218 if namespace ~= current_ns then
185 propattr = {xmlns = namespace} 219 propattr = {xmlns = namespace}
186 end 220 end