Mercurial > hg > ltpda
comparison m-toolbox/classes/+utils/@xml/xmlwrite.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0afece42f48 |
---|---|
1 % XMLWRITE Add an object to a xml DOM project. | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % | |
4 % DESCRIPTION: XMLWRITE Add an object to a xml DOM project. | |
5 % | |
6 % EXAMPLE: xml = com.mathworks.xml.XMLUtils.createDocument('ltpda_object'); | |
7 % parent = xml.getDocumentElement; | |
8 % | |
9 % xmlwrite(a, xml, parent, ''); | |
10 % | |
11 % xmlwrite('foo.xml', xml); | |
12 % | |
13 % FORMAT: This function writes the object into the following xml format: | |
14 % | |
15 % ---------------------- ltpda_object ---------------------- | |
16 % | |
17 % <ltpda_object> | |
18 % | |
19 % --> <object> ... | |
20 % --> <cell> ... | |
21 % | |
22 % </ltpda_object> | |
23 % | |
24 % ------------------------- object ------------------------- | |
25 % | |
26 % <object> ('type' - attribute) | |
27 % | |
28 % <property> ... | |
29 % | |
30 % </object> | |
31 % | |
32 % ------------------------ property ------------------------ | |
33 % -------------------------- cell -------------------------- | |
34 % | |
35 % <property> ('type', 'prop_name' -attributes) | |
36 % OR <cell> ('type' -attribute) | |
37 % | |
38 % --> atomic element | |
39 % - empty cell | |
40 % - empty double | |
41 % - empty char | |
42 % - char | |
43 % - double | |
44 % - logical | |
45 % - java (necessary for timezone) | |
46 % --> <cell> ... | |
47 % --> <object> ... | |
48 % --> <real_data> ... | |
49 % <imag_data> ... | |
50 % | |
51 % </property> | |
52 % OR </cell> | |
53 % | |
54 % ------- real_data --------|-------- imag_data -------- | |
55 % | | |
56 % <real_data>('type'-attribute) | <imag_data> ('type' -attribute) | |
57 % ('shape'-attribute)| ('shape'-attribute) | |
58 % | | |
59 % --> <matrix> ... | --> <matrix> ... | |
60 % --> <vector> ... | --> <vector> ... | |
61 % | | |
62 % </real_data> | </imag_data> | |
63 % | | |
64 % --------- matrix -------------------- vector --------- | |
65 % | | |
66 % <matrix> ('type' -attribute) | <vector> ('type' -attribute) | |
67 % | | |
68 % row vector (double) | column vector (double) | |
69 % | | |
70 % </matrix> | </vector> | |
71 % | |
72 % SYMBOLS: --> Marks a choice between alternatives. | |
73 % ... Indicate that an element may be repeated. | |
74 % | |
75 % VERSION: $Id: xmlwrite.m,v 1.7 2011/03/28 17:04:27 ingo Exp $ | |
76 % | |
77 % HISTORY: 31-01-2008 Diepholz | |
78 % Creation | |
79 % | |
80 % SEE ALSO: utils.xml.xmlread | |
81 % | |
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
83 function varargout = xmlwrite(objs, xml, parent, property_name) | |
84 | |
85 %%%%%% Workaround for saving as the new XML format %%%%%% | |
86 ltpda_version = getappdata(0, 'ltpda_version'); | |
87 if (utils.helper.ver2num(ltpda_version) > utils.helper.ver2num('2.3')) || ... | |
88 (strcmp(strtok(ltpda_version), '2.3')) | |
89 %%%%%%%%%%%%%%%%%% reading of a new XML file %%%%%%%%%%%%%%%%%% | |
90 | |
91 % Create history root node | |
92 % The attachToDom methods will attach their histories to this node. | |
93 historyRootNode = xml.createElement('historyRoot'); | |
94 parent.appendChild(historyRootNode); | |
95 | |
96 % Write objects | |
97 collectedHist = objs.attachToDom(xml, parent, []); | |
98 return | |
99 end | |
100 | |
101 %%%%%% If the property_name is filled then create a new property node %%%%% | |
102 if ~isempty(property_name) | |
103 shape = sprintf('%dx%d', size(objs,1), size(objs,2)); | |
104 prop_node = xml.createElement('property'); | |
105 prop_node.setAttribute('prop_name', property_name); | |
106 prop_node.setAttribute('shape', shape); | |
107 prop_node.setAttribute('type', class(objs)); | |
108 parent.appendChild(prop_node); | |
109 parent = prop_node; | |
110 end | |
111 | |
112 %%%%%%%%%%%%%%%% The object is a class object or a struct %%%%%%%%%%%%%%%%% | |
113 if (isobject(objs) || isstruct(objs)) && ~isa(objs, 'sym') | |
114 | |
115 if isa(objs, 'ltpda_obj') | |
116 %%%%% Skip empty fields for unser objects %%%%% | |
117 for ii = 1:numel(objs) | |
118 obj = objs(ii); | |
119 shape = sprintf('%dx%d', size(objs,1), size(objs,2)); | |
120 obj_node = xml.createElement('object'); | |
121 obj_node.setAttribute('type', class(obj)); | |
122 obj_node.setAttribute('shape', shape); | |
123 parent.appendChild(obj_node); | |
124 if isa(obj, 'minfo') | |
125 | |
126 % we don't write all fields | |
127 info = obj.getEncodedString; | |
128 obj_node.setAttribute('info', info); | |
129 | |
130 elseif isa(obj, 'provenance') | |
131 | |
132 % write info | |
133 info = obj.getEncodedString; | |
134 obj_node.setAttribute('info', info); | |
135 | |
136 elseif isa(obj, 'param') | |
137 | |
138 obj_node.setAttribute('key', obj.key'); | |
139 val = obj.getDefaultVal; | |
140 utils.xml.xmlwrite(val, xml, obj_node, 'value'); | |
141 | |
142 elseif isa(obj, 'time') | |
143 | |
144 % write utc_epoch_milli | |
145 obj_node.setAttribute('utc', num2str(obj.utc_epoch_milli)); | |
146 % write timezone | |
147 obj_node.setAttribute('timezone', char(obj.timezone.getID)); | |
148 % write timeformat | |
149 obj_node.setAttribute('timeformat', obj.timeformat); | |
150 | |
151 else | |
152 fields = getFieldnames(obj); | |
153 for jj = 1:length(fields) | |
154 if ~isempty(obj.(fields{jj})) || any(size(obj.(fields{jj}))) | |
155 % handle some fields as attributes | |
156 if strcmp(fields{jj}, 'name') | |
157 obj_node.setAttribute('name', obj.name); | |
158 elseif strcmp(fields{jj}, 'description') | |
159 obj_node.setAttribute('description', obj.description); | |
160 elseif strcmp(fields{jj}, 'UUID') | |
161 obj_node.setAttribute('UUID', obj.UUID); | |
162 elseif strcmp(fields{jj}, 'created') | |
163 obj_node.setAttribute('created', num2str(obj.created)); | |
164 elseif strcmp(fields{jj}, 'proctime') | |
165 obj_node.setAttribute('proctime', num2str(obj.proctime)); | |
166 else | |
167 utils.xml.xmlwrite(obj.(fields{jj}), xml, obj_node, fields{jj}); | |
168 end | |
169 end | |
170 end | |
171 end | |
172 end | |
173 else | |
174 %%%%% Don't skip empty fields for structures and other %%%%% | |
175 for ii = 1:numel(objs) | |
176 obj = objs(ii); | |
177 shape = sprintf('%dx%d', size(objs,1), size(objs,2)); | |
178 obj_node = xml.createElement('object'); | |
179 obj_node.setAttribute('type', class(obj)); | |
180 obj_node.setAttribute('shape', shape); | |
181 parent.appendChild(obj_node); | |
182 fields = fieldnames(obj); | |
183 for jj = 1:length(fields) | |
184 utils.xml.xmlwrite(obj.(fields{jj}), xml, obj_node, fields{jj}); | |
185 end | |
186 end | |
187 end | |
188 | |
189 %%%%%%%%%%%%%%%%%%%%%%% The object is a java object %%%%%%%%%%%%%%%%%%%%%%% | |
190 elseif isjava(objs) | |
191 if strcmp(class(objs), 'sun.util.calendar.ZoneInfo') | |
192 content = xml.createTextNode(char(objs.getID)); | |
193 parent.appendChild(content); | |
194 else | |
195 error('### Unknown Java'); | |
196 end | |
197 | |
198 %%%%%%%%%%%%%%%%%%%%%%% The object is a cell object %%%%%%%%%%%%%%%%%%%%%%% | |
199 elseif iscell(objs) | |
200 | |
201 for ii = 1:numel(objs) | |
202 obj = objs{ii}; | |
203 shape = sprintf('%dx%d', size(obj,1), size(obj,2)); | |
204 cell_node = xml.createElement('cell'); | |
205 cell_node.setAttribute('type', class(obj)); | |
206 cell_node.setAttribute('prop_name', property_name); | |
207 cell_node.setAttribute('shape', shape); | |
208 parent.appendChild(cell_node); | |
209 utils.xml.xmlwrite(obj, xml, cell_node, ''); | |
210 end | |
211 | |
212 %%%%%%%%%%%%%%%%%%%% The object is a character string %%%%%%%%%%%%%%%%%%%%% | |
213 elseif ischar(objs) | |
214 | |
215 % We mask the line break '\n' with a new identifier because we got | |
216 % problems with saving into the database. | |
217 objs_txt = objs; | |
218 objs_txt = strrep(objs_txt, '\n', '<NEW_LINE>'); | |
219 | |
220 % Replace the first and last DOLLAR $ of an version string with CVS_TAG | |
221 if ~isempty(objs_txt) && (objs_txt(1) == '$') && (objs_txt(end) == '$') && (strcmp(property_name, 'version') || strcmp(property_name, 'mversion')) | |
222 objs_txt = strrep(objs_txt, '$', 'CVS_TAG'); | |
223 % objs_txt = ['CVS_TAG', objs_txt(2:end-1), 'CVS_TAG']; | |
224 end | |
225 | |
226 % Set the shape of the node again because it is possible that we | |
227 % replaced '\n' with '<NEW_LINE>'. | |
228 parent.setAttribute('shape', sprintf('%dx%d', size(objs_txt,1), size(objs_txt,2))); | |
229 | |
230 objs_txt = reshape(objs_txt, 1, []); | |
231 content = xml.createTextNode(objs_txt); | |
232 parent.appendChild(content); | |
233 | |
234 %%%%%%%%%%%%%%%%%%%%%%%%% The object is a logical %%%%%%%%%%%%%%%%%%%%%%%%% | |
235 elseif islogical(objs) | |
236 | |
237 content = xml.createTextNode(mat2str(objs)); | |
238 parent.appendChild(content); | |
239 | |
240 %%%%%%%%%%%%%%%%%%%%%%%%% The object is a number %%%%%%%%%%%%%%%%%%%%%%%%%% | |
241 elseif isnumeric(objs) || isa(objs, 'sym') | |
242 | |
243 %%%%% objs is a singel value %%%%% | |
244 if (size(objs,1) == 1) && (size(objs,2) == 1) || size(objs,1) == 0 || size(objs,2) == 0 | |
245 if strcmp(class(objs), 'sym') | |
246 number_str = char(objs, 20); | |
247 else | |
248 if isreal(objs) | |
249 number_str = sprintf('%.17g', objs); | |
250 else | |
251 number_str = num2str(objs, 20); | |
252 end | |
253 end | |
254 content = xml.createTextNode(number_str); | |
255 parent.appendChild(content); | |
256 | |
257 %%%%% objs is a matrix %%%%% | |
258 elseif (size(objs,1) > 1) && (size(objs,2) > 1) | |
259 | |
260 xml_addmatrix(objs, xml, parent); | |
261 | |
262 %%%%% objs is a vector %%%%% | |
263 elseif (size(objs,1) > 1) || (size(objs,2) > 1) | |
264 | |
265 xml_addvector(objs, xml, parent); | |
266 | |
267 end | |
268 | |
269 else | |
270 error('### unknown type [%s]', class(objs)); | |
271 end | |
272 end | |
273 | |
274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
275 % | |
276 % DESCRIPTION: XML_ADDVECTOR Add a vector element to the xml node. The element | |
277 % have the form: | |
278 % | |
279 % REAL DATA: <real_data type="vector"> | |
280 % <vector type="double"> 1 2 3 4 5 6 7 8 9 10</vector> | |
281 % <vector type="double">11 12 13 14 15 16 17 18 19 20</vector> | |
282 % </real_data> | |
283 % | |
284 % COMPLEX DATA:<real_data type="vector"> | |
285 % <vector type="double"> 1 2 3 4 5 6 7 8 9 10</vector> | |
286 % <vector type="double">11 12 13 14 15 16 17 18 19 20</vector> | |
287 % </real_data> | |
288 % | |
289 % <imag_data type="vector"> | |
290 % <vector type="double"> 1 2 3 4 5 6 7 8 9 10</vector> | |
291 % <vector type="double">11 12 13 14 15 16 17 18 19 20</vector> | |
292 % </imag_data> | |
293 % | |
294 % The vector objs will be split into several parts dependent from | |
295 % the maximum size in one vector element. | |
296 % Each part creates its own vectror element. | |
297 % | |
298 % HISTORY: 31-01-2008 Diepholz | |
299 % Creation | |
300 % | |
301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
302 function xml_addvector(objs, xml, parent) | |
303 | |
304 n_min = 50000; | |
305 header_displayed = true; | |
306 | |
307 shape = sprintf('%dx%d', size(objs,1), size(objs,2)); | |
308 | |
309 %%%%% Real data %%%%% | |
310 node_real = xml.createElement('real_data'); | |
311 node_real.setAttribute('type', 'vector'); | |
312 node_real.setAttribute('shape', shape); | |
313 %%% Set the parent attribute 'type' to vector | |
314 parent.setAttribute('type', 'vector'); | |
315 parent.appendChild(node_real); | |
316 | |
317 idx = 1; | |
318 Ndata = length(objs); | |
319 n = min(n_min, Ndata); | |
320 while idx-1 <= Ndata | |
321 header_displayed = TerminalOutput(parent, header_displayed, true, 'vector', idx+n-1); | |
322 if isa(objs, 'sym') | |
323 number_str = strtrim(char(objs(idx:min(Ndata,idx+n-1)))); | |
324 else | |
325 number_str = strtrim(utils.helper.num2str(real(objs(idx:min(Ndata,idx+n-1))))); | |
326 end | |
327 if ~isempty(number_str) | |
328 item = xml.createElement('vector'); | |
329 item.setAttribute('type', class(objs)); | |
330 content = xml.createTextNode(number_str); | |
331 node_real.appendChild(item); | |
332 item.appendChild(content); | |
333 end | |
334 idx = idx + n; | |
335 end | |
336 | |
337 %%%%% Imaginary data %%%%% | |
338 if ~isreal(objs) && ~isa(objs, 'sym') | |
339 header_displayed = true; | |
340 node_imag = xml.createElement('imag_data'); | |
341 node_imag.setAttribute('type', 'vector') | |
342 node_imag.setAttribute('shape', shape); | |
343 parent.appendChild(node_imag); | |
344 | |
345 idx = 1; | |
346 while idx-1 <= Ndata | |
347 header_displayed = TerminalOutput(parent, header_displayed, false, 'vector', idx+n-1); | |
348 number_str = strtrim(utils.helper.num2str(imag(objs(idx:min(Ndata,idx+n-1))))); | |
349 if ~isempty(number_str) | |
350 item = xml.createElement('vector'); | |
351 item.setAttribute('type', class(objs)); | |
352 content = xml.createTextNode(number_str); | |
353 node_imag.appendChild(item); | |
354 item.appendChild(content); | |
355 end | |
356 idx = idx + n; | |
357 end | |
358 end | |
359 end | |
360 | |
361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
362 % | |
363 % DESCRIPTION: XML_ADDMATRIX Add a matrix element to the xml node. The element | |
364 % have the form: | |
365 % | |
366 % REAL DATA: <real_data type="matrix"> | |
367 % <matrix type="double">1 2 3</matrix> | |
368 % <matrix type="double">4 5 6</matrix> | |
369 % <matrix type="double">7 8 9</matrix> | |
370 % </real_data> | |
371 % | |
372 % COMPLEX DATA:<real_data type="matrix"> | |
373 % <matrix type="double">1 2 3</matrix> | |
374 % <matrix type="double">4 5 6</matrix> | |
375 % <matrix type="double">7 8 9</matrix> | |
376 % </real_data> | |
377 % | |
378 % <imag_data type="matrix"> | |
379 % <matrix type="double">9 8 7</matrix> | |
380 % <matrix type="double">6 5 4</matrix> | |
381 % <matrix type="double">3 2 1</matrix> | |
382 % </imag_data> | |
383 % | |
384 % Each row in objs creates a matrix element. | |
385 % | |
386 % HISTORY: 31-01-2008 Diepholz | |
387 % Creation | |
388 % | |
389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
390 function xml_addmatrix(objs, xml, parent) | |
391 | |
392 shape = sprintf('%dx%d', size(objs,1), size(objs,2)); | |
393 header_displayed = true; | |
394 | |
395 %%% Get the property name only for displaying the property name | |
396 | |
397 %%%%% Real data %%%%% | |
398 node_real = xml.createElement('real_data'); | |
399 node_real.setAttribute('type', 'matrix'); | |
400 node_real.setAttribute('shape', shape); | |
401 %%% Set the parent attribute 'type' to matrix | |
402 parent.setAttribute('type', 'matrix'); | |
403 parent.appendChild(node_real); | |
404 | |
405 for ii = 1:size(objs,1) | |
406 if strcmp(class(objs), 'sym') | |
407 number_str = strtrim(char(objs(ii,:))); | |
408 else | |
409 number_str = strtrim(utils.helper.num2str(real(objs(ii,:)))); | |
410 end | |
411 if ~isempty(number_str) | |
412 item = xml.createElement('matrix'); | |
413 item.setAttribute('type', class(objs)); | |
414 content = xml.createTextNode(number_str); | |
415 node_real.appendChild(item); | |
416 item.appendChild(content); | |
417 end | |
418 end | |
419 | |
420 TerminalOutput(parent, header_displayed, true, 'matrix', ii); | |
421 | |
422 %%%%% Imaginary data %%%%% | |
423 if ~isreal(objs) && ~isa(objs, 'sym') | |
424 node_imag = xml.createElement('imag_data'); | |
425 node_imag.setAttribute('type', 'matrix'); | |
426 node_imag.setAttribute('shape', shape); | |
427 parent.appendChild(node_imag); | |
428 for ii = 1:size(objs,1) | |
429 number_str = strtrim(utils.helper.num2str(imag(objs(ii,:)))); | |
430 if ~isempty(number_str) | |
431 item = xml.createElement('matrix'); | |
432 item.setAttribute('type', class(objs)); | |
433 content = xml.createTextNode(number_str); | |
434 node_imag.appendChild(item); | |
435 item.appendChild(content); | |
436 end | |
437 end | |
438 TerminalOutput(parent, header_displayed, false, 'matrix', ii); | |
439 end | |
440 end | |
441 | |
442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
443 % | |
444 % DESCRIPTION: Displays the terminal output. | |
445 % | |
446 % HISTORY: 31-01-2008 Diepholz | |
447 % Creation | |
448 % | |
449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
450 function header_displayed = TerminalOutput(parent, header_displayed, isreal_num, obj_type, number) | |
451 | |
452 import utils.const.* | |
453 | |
454 THRESHOLD_DISP_MATRIX = 10; | |
455 THRESHOLD_DISP_VECTOR = 1000; | |
456 | |
457 showing = false; | |
458 | |
459 if strcmp(obj_type, 'matrix') | |
460 if number >= THRESHOLD_DISP_MATRIX | |
461 showing = true; | |
462 end | |
463 add_text = 'matrix lines'; | |
464 else | |
465 if number >= THRESHOLD_DISP_VECTOR | |
466 showing = true; | |
467 end | |
468 add_text = 'data samples'; | |
469 end | |
470 | |
471 if showing | |
472 | |
473 if header_displayed | |
474 if parent.hasAttribute('prop_name') | |
475 disp_prop_name = char(parent.getAttribute('prop_name')); | |
476 else | |
477 disp_prop_name = 'Unknown Property Name'; | |
478 end | |
479 utils.helper.msg(msg.PROC2, 'Writing property: %s', disp_prop_name); | |
480 if isreal_num | |
481 utils.helper.msg(msg.PROC2, 'Writing real data'); | |
482 else | |
483 utils.helper.msg(msg.PROC2, 'Writing imag data'); | |
484 end | |
485 | |
486 header_displayed = false; | |
487 end | |
488 | |
489 utils.helper.msg(msg.PROC3, 'Writing %d %s', number, add_text); | |
490 end | |
491 end | |
492 | |
493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
494 % | |
495 % FUNCTION: getFieldnames | |
496 % | |
497 % DESCRIPTION: Retruns the field names which should be storred in a XML file. | |
498 % | |
499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
500 function fields = getFieldnames(obj) | |
501 meta = eval(['?' class(obj)]); | |
502 metaProp = [meta.Properties{:}]; | |
503 props = {metaProp(:).Name}; | |
504 propGetAccess = strcmpi({metaProp(:).GetAccess}, 'public'); | |
505 propDependent = [metaProp(:).Dependent]; | |
506 fields = props(propGetAccess & ~propDependent); | |
507 end |