-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathconvert.m
149 lines (138 loc) · 5.48 KB
/
convert.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
146
147
148
149
function s = convert(tree,uid)
% XMLTREE/CONVERT Converter an XML tree in a Matlab structure
%
% tree - XMLTree object
% uid - uid of the root of the subtree, if provided.
% Default is root
% s - converted structure
%_______________________________________________________________________
%
% Convert an xmltree into a Matlab structure, when possible.
% When several identical tags are present, a cell array is used.
% The root tag is not saved in the structure.
% If provided, only the structure corresponding to the subtree defined
% by the uid UID is returned.
%_______________________________________________________________________
% Copyright (C) 2002-2008 http://www.artefact.tk/
% Guillaume Flandin <guillaume@artefact.tk>
% $Id: convert.m 3756 2010-03-05 18:43:37Z guillaume $
% Exemple:
% tree: <toto><titi>field1</titi><tutu>field2</tutu><titi>field3</titi></toto>
% toto = convert(tree);
% <=> toto = struct('titi',{{'field1', 'field3'}},'tutu','field2')
error(nargchk(1,2,nargin));
% Get the root uid of the output structure
if nargin == 1
% Get the root uid of the XML tree
root_uid = root(tree);
else
% Uid provided by user
root_uid = uid;
end
% Initialize the output structure
% struct([]) should be used but this only works with Matlab 6
% So we create a field that we delete at the end
%s = struct(get(tree,root_uid,'name'),''); % struct([])
s = struct('deletedummy','');
%s = sub_convert(tree,s,root_uid,{get(tree,root_uid,'name')});
s = sub_convert(tree,s,root_uid,{});
s = rmfield(s,'deletedummy');
%=======================================================================
function s = sub_convert(tree,s,uid,arg)
type = get(tree,uid,'type');
switch type
case 'element'
child = children(tree,uid);
l = {};
ll = {};
for i=1:length(child)
if isfield(tree,child(i),'name')
ll = { ll{:}, get(tree,child(i),'name') };
end
end
for i=1:length(child)
if isfield(tree,child(i),'name')
name = get(tree,child(i),'name');
nboccur = sum(ismember(l,name));
nboccur2 = sum(ismember(ll,name));
l = { l{:}, name };
if nboccur || (nboccur2>1)
arg2 = { arg{:}, name, {nboccur+1} };
else
arg2 = { arg{:}, name};
end
else
arg2 = arg;
end
s = sub_convert(tree,s,child(i),arg2);
end
if isempty(child)
s = sub_setfield(s,arg{:},'');
end
%- saving attributes : does not work with <a t='q'>b</a>
%- but ok with <a t='q'><c>b</c></a>
% attrb = attributes(tree,'get',uid); %-
% if ~isempty(attrb) %-
% arg2 = {arg{:} 'attributes'}; %-
% s = sub_setfield(s,arg2{:},attrb); %-
% end %-
case 'chardata'
s = sub_setfield(s,arg{:},get(tree,uid,'value'));
%- convert strings into their Matlab equivalent when possible
%- e.g. string '3.14159' becomes double scalar 3.14159
% v = get(tree,uid,'value'); %-
% cv = str2num(v); %-
% if isempty(cv) %-
% s = sub_setfield(s,arg{:},v); %-
% else %-
% s = sub_setfield(s,arg{:},cv); %-
% end %-
case 'cdata'
s = sub_setfield(s,arg{:},get(tree,uid,'value'));
case 'pi'
% Processing instructions are evaluated if possible
app = get(tree,uid,'target');
switch app
case {'matlab',''}
s = sub_setfield(s,arg{:},eval(get(tree,uid,'value')));
case 'unix'
s = sub_setfield(s,arg{:},unix(get(tree,uid,'value')));
case 'dos'
s = sub_setfield(s,arg{:},dos(get(tree,uid,'value')));
case 'system'
s = sub_setfield(s,arg{:},system(get(tree,uid,'value')));
otherwise
try
s = sub_setfield(s,arg{:},feval(app,get(tree,uid,'value')));
catch
warning('[XMLTREE] Unknown target application');
end
end
case 'comment'
% Comments are forgotten
otherwise
warning(sprintf('Type %s unknown : not saved',get(tree,uid,'type')));
end
%=======================================================================
function s = sub_setfield(s,varargin)
% Same as setfield but using '{}' rather than '()'
%if (isempty(varargin) | length(varargin) < 2)
% error('Not enough input arguments.');
%end
subs = varargin(1:end-1);
for i = 1:length(varargin)-1
if (isa(varargin{i}, 'cell'))
types{i} = '{}';
elseif ischar(varargin{i})
types{i} = '.';
subs{i} = varargin{i}; %strrep(varargin{i},' ',''); % deblank field name
else
error('Inputs must be either cell arrays or strings.');
end
end
% Perform assignment
try
s = builtin('subsasgn', s, struct('type',types,'subs',subs), varargin{end});
catch
error(lasterr)
end