Comparison

util/datamapper.lua @ 11436:5df9ffc25bb4

util.datamapper: Add 'unparse' for turning tables into XML
author Kim Alvefur <zash@zash.se>
date Sun, 07 Mar 2021 00:57:36 +0100
parent 11435:a1fa6202fa13
child 11437:87a684df4b65
comparison
equal deleted inserted replaced
11435:a1fa6202fa13 11436:5df9ffc25bb4
91 if schema.type == "object" then 91 if schema.type == "object" then
92 return parse_object(schema, s) 92 return parse_object(schema, s)
93 end 93 end
94 end 94 end
95 95
96 return {parse = parse} 96 local function unparse(schema, t, current_name, current_ns)
97 if schema.type == "object" then
98
99 if schema.xml then
100 if schema.xml.name then
101 current_name = schema.xml.name
102 end
103 if schema.xml.namespace then
104 current_ns = schema.xml.namespace
105 end
106
107 end
108
109 local out = st.stanza(current_name, {xmlns = current_ns})
110
111 for prop, propschema in pairs(schema.properties) do
112 local v = t[prop]
113
114 if v ~= nil then
115 local proptype
116 if type(propschema) == "table" then
117 proptype = propschema.type
118 elseif type(propschema) == "string" then
119 proptype = propschema
120 end
121
122 local name = prop
123 local namespace = current_ns
124 local prefix = nil
125 local is_attribute = false
126 local is_text = false
127
128 if type(propschema) == "table" and propschema.xml then
129
130 if propschema.xml.name then
131 name = propschema.xml.name
132 end
133 if propschema.xml.namespace then
134 namespace = propschema.xml.namespace
135 end
136
137 if propschema.xml.prefix then
138 prefix = propschema.xml.prefix
139 end
140
141 if propschema.xml.attribute then
142 is_attribute = true
143 elseif propschema.xml.text then
144 is_text = true
145 end
146 end
147
148 if is_attribute then
149 local attr = name
150 if prefix then
151 attr = prefix .. ":" .. name
152 elseif namespace ~= current_ns then
153 attr = namespace .. "\1" .. name
154 end
155
156 if proptype == "string" and type(v) == "string" then
157 out.attr[attr] = v
158 elseif proptype == "number" and type(v) == "number" then
159 out.attr[attr] = string.format("%g", v)
160 elseif proptype == "integer" and type(v) == "number" then
161 out.attr[attr] = string.format("%d", v)
162 elseif proptype == "boolean" then
163 out.attr[attr] = v and "1" or "0"
164 end
165 elseif is_text then
166 if type(v) == "string" then
167 out:text(v)
168 end
169 else
170 local propattr
171 if namespace ~= current_ns then
172 propattr = {xmlns = namespace}
173 end
174 if proptype == "string" and type(v) == "string" then
175 out:text_tag(name, v, propattr)
176 elseif proptype == "number" and type(v) == "number" then
177 out:text_tag(name, string.format("%g", v), propattr)
178 elseif proptype == "integer" and type(v) == "number" then
179 out:text_tag(name, string.format("%d", v), propattr)
180 elseif proptype == "boolean" and type(v) == "boolean" then
181 out:text_tag(name, v and "1" or "0", propattr)
182 elseif proptype == "object" and type(propschema) == "table" and type(v) == "table" then
183 local c = unparse(propschema, v, name, namespace);
184 if c then
185 out:add_direct_child(c);
186 end
187
188 end
189 end
190 end
191 end
192 return out
193
194 end
195 end
196
197 return {parse = parse; unparse = unparse}