-
Notifications
You must be signed in to change notification settings - Fork 64
/
savexml.m
145 lines (135 loc) · 5.12 KB
/
savexml.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
function savexml(filename, varargin)
%SAVEXML Save workspace variables to disk in XML.
% SAVEXML FILENAME saves all workspace variables to the XML-file
% named FILENAME.xml. The data may be retrieved with LOADXML. if
% FILENAME has no extension, .xml is assumed.
%
% SAVE, by itself, creates the XML-file named 'matlab.xml'. It is
% an error if 'matlab.xml' is not writable.
%
% SAVE FILENAME X saves only X.
% SAVE FILENAME X Y Z saves X, Y, and Z. The wildcard '*' can be
% used to save only those variables that match a pattern.
%
% SAVE ... -APPEND adds the variables to an existing file.
%
% Use the functional form of SAVE, such as SAVE(filename','var1','var2'),
% when the filename or variable names are stored in strings.
%
% See also SAVE, MAT2XML, XMLTREE.
% Copyright 2003 Guillaume Flandin.
% $Revision: 4393 $ $Date: 2003/07/10 13:50 $
% $Id: savexml.m 4393 2011-07-18 14:52:32Z guillaume $
if nargin == 0
filename = 'matlab.xml';
fprintf('\nSaving to: %s\n\n',filename);
else
if ~ischar(filename)
error('[SAVEXML] Argument must contain a string.');
end
[pathstr,name,ext] = fileparts(filename);
if isempty(ext)
filename = [filename '.xml'];
end
end
if nargin <= 1, varargin = {'*'}; end
if nargout > 0
error('[SAVEXML] Too many output arguments.');
end
if strcmpi(varargin{end},'-append')
if length(varargin) > 1
varargin = varargin(1:end-1);
else
varargin = {'*'};
end
if exist(filename,'file')
% TODO % No need to parse the whole tree ? detect duplicate variables ?
t = xmltree(filename);
else
error(sprintf(...
'[SAVEXML] Unable to write file %s: file does not exist.',filename));
end
else
t = xmltree('<matfile/>');
end
for i=1:length(varargin)
v = evalin('caller',['whos(''' varargin{i} ''')']);
if isempty(v)
error(['[SAVEXML] Variable ''' varargin{i} ''' not found.']);
end
for j=1:length(v)
[t, uid] = add(t,root(t),'element',v(j).name);
t = attributes(t,'add',uid,'type',v(j).class);
t = attributes(t,'add',uid,'size',xml_num2str(v(j).size));
t = xml_var2xml(t,evalin('caller',v(j).name),uid);
end
end
save(t,filename);
%=======================================================================
function t = xml_var2xml(t,v,uid)
switch class(v)
case {'double','single','logical'}
if ~issparse(v)
t = add(t,uid,'chardata',xml_num2str(v));
else % logical
[i,j,s] = find(v);
[t, uid2] = add(t,uid,'element','row');
t = attributes(t,'add',uid2,'size',xml_num2str(size(i)));
t = add(t,uid2,'chardata',xml_num2str(i));
[t, uid2] = add(t,uid,'element','col');
t = attributes(t,'add',uid2,'size',xml_num2str(size(j)));
t = add(t,uid2,'chardata',xml_num2str(j));
[t, uid2] = add(t,uid,'element','val');
t = attributes(t,'add',uid2,'size',xml_num2str(size(s)));
t = add(t,uid2,'chardata',xml_num2str(s));
end
case 'struct'
names = fieldnames(v);
for j=1:prod(size(v))
for i=1:length(names)
[t, uid2] = add(t,uid,'element',names{i});
t = attributes(t,'add',uid2,'index',num2str(j));
t = attributes(t,'add',uid2,'type',...
class(getfield(v(j),names{i})));
t = attributes(t,'add',uid2,'size', ...
xml_num2str(size(getfield(v(j),names{i}))));
t = xml_var2xml(t,getfield(v(j),names{i}),uid2);
end
end
case 'cell'
for i=1:prod(size(v))
[t, uid2] = add(t,uid,'element','cell');
% TODO % special handling of cellstr ?
t = attributes(t,'add',uid2,'index',num2str(i));
t = attributes(t,'add',uid2,'type',class(v{i}));
t = attributes(t,'add',uid2,'size',xml_num2str(size(v{i})));
t = xml_var2xml(t,v{i},uid2);
end
case 'char'
% TODO % char values should be in CData
if size(v,1) > 1
t = add(t,uid,'chardata',v'); % row-wise order
else
t = add(t,uid,'chardata',v);
end
case {'int8','uint8','int16','uint16','int32','uint32'}
[t, uid] = add(t,uid,'element',class(v));
% TODO % Handle integer formats (cannot use sprintf or num2str)
otherwise
if ismember('serialize',methods(class(v)))
% TODO % is CData necessary for class output ?
t = add(t,uid,'cdata',serialize(v));
else
warning(sprintf(...
'[SAVEXML] Cannot convert from %s to XML.',class(v)));
end
end
%=======================================================================
function s = xml_num2str(n)
% TODO % use format ?
if isempty(n)
s = '[]';
else
s = ['[' sprintf('%g ',n(1:end-1))];
s = [s num2str(n(end)) ']'];
end