1 | function s = convert(tree,uid) |
---|
2 | % XMLTREE/CONVERT Converter an XML tree in a Matlab structure |
---|
3 | % |
---|
4 | % tree - XMLTree object |
---|
5 | % uid - uid of the root of the subtree, if provided. |
---|
6 | % Default is root |
---|
7 | % s - converted structure |
---|
8 | %_______________________________________________________________________ |
---|
9 | % |
---|
10 | % Convert an xmltree into a Matlab structure, when possible. |
---|
11 | % When several identical tags are present, a cell array is used. |
---|
12 | % The root tag is not saved in the structure. |
---|
13 | % If provided, only the structure corresponding to the subtree defined |
---|
14 | % by the uid UID is returned. |
---|
15 | %_______________________________________________________________________ |
---|
16 | % @(#)convert.m Guillaume Flandin 02/04/11 |
---|
17 | |
---|
18 | % Exemple: |
---|
19 | % tree: <toto><titi>field1</titi><tutu>field2</tutu><titi>field3</titi></toto> |
---|
20 | % toto = convert(tree); |
---|
21 | % <=> toto = struct('titi',{{'field1', 'field3'}},'tutu','field2') |
---|
22 | |
---|
23 | error(nargchk(1,2,nargin)); |
---|
24 | |
---|
25 | % Get the root uid of the output structure |
---|
26 | if nargin == 1 |
---|
27 | % Get the root uid of the XML tree |
---|
28 | root_uid = root(tree); |
---|
29 | else |
---|
30 | % Uid provided by user |
---|
31 | root_uid = uid; |
---|
32 | end |
---|
33 | |
---|
34 | % Initialize the output structure |
---|
35 | % struct([]) should be used but this only works with Matlab 6 |
---|
36 | % So we create a field that we delete at the end |
---|
37 | %s = struct(get(tree,root_uid,'name'),''); % struct([]) |
---|
38 | s = struct('deletedummy',''); |
---|
39 | |
---|
40 | %s = sub_convert(tree,s,root_uid,{get(tree,root_uid,'name')}); |
---|
41 | s = sub_convert(tree,s,root_uid,{}); |
---|
42 | |
---|
43 | s = rmfield(s,'deletedummy'); |
---|
44 | |
---|
45 | %======================================================================= |
---|
46 | function s = sub_convert(tree,s,uid,arg) |
---|
47 | type = get(tree,uid,'type'); |
---|
48 | switch type |
---|
49 | case 'element' |
---|
50 | child = children(tree,uid); |
---|
51 | l = {}; |
---|
52 | ll = {}; |
---|
53 | for i=1:length(child) |
---|
54 | if isfield(tree,child(i),'name') |
---|
55 | ll = { ll{:}, get(tree,child(i),'name') }; |
---|
56 | end |
---|
57 | end |
---|
58 | for i=1:length(child) |
---|
59 | if isfield(tree,child(i),'name') |
---|
60 | name = get(tree,child(i),'name'); |
---|
61 | nboccur = sum(ismember(l,name)); |
---|
62 | nboccur2 = sum(ismember(ll,name)); |
---|
63 | l = { l{:}, name }; |
---|
64 | if nboccur | (nboccur2>1) |
---|
65 | arg2 = { arg{:}, name, {nboccur+1} }; |
---|
66 | else |
---|
67 | arg2 = { arg{:}, name}; |
---|
68 | end |
---|
69 | else |
---|
70 | arg2 = arg; |
---|
71 | end |
---|
72 | s = sub_convert(tree,s,child(i),arg2); |
---|
73 | end |
---|
74 | if isempty(child) |
---|
75 | s = sub_setfield(s,arg{:},''); |
---|
76 | end |
---|
77 | %- saving attributes : does not work with <a t='q'>b</a> |
---|
78 | %- but ok with <a t='q'><c>b</c></a> |
---|
79 | % attrb = attributes(tree,'get',uid); %- |
---|
80 | % if ~isempty(attrb) %- |
---|
81 | % arg2 = {arg{:} 'attributes'}; %- |
---|
82 | % s = sub_setfield(s,arg2{:},attrb); %- |
---|
83 | % end %- |
---|
84 | case 'chardata' |
---|
85 | s = sub_setfield(s,arg{:},get(tree,uid,'value')); |
---|
86 | %- convert strings into their Matlab equivalent when possible |
---|
87 | %- e.g. string '3.14159' becomes double scalar 3.14159 |
---|
88 | % v = get(tree,uid,'value'); %- |
---|
89 | % cv = str2num(v); %- |
---|
90 | % if isempty(cv) %- |
---|
91 | % s = sub_setfield(s,arg{:},v); %- |
---|
92 | % else %- |
---|
93 | % s = sub_setfield(s,arg{:},cv); %- |
---|
94 | % end %- |
---|
95 | case 'cdata' |
---|
96 | s = sub_setfield(s,arg{:},get(tree,uid,'value')); |
---|
97 | case 'pi' |
---|
98 | % Processing instructions are evaluated if possible |
---|
99 | app = get(tree,uid,'target'); |
---|
100 | switch app |
---|
101 | case {'matlab',''} |
---|
102 | s = sub_setfield(s,arg{:},eval(get(tree,uid,'value'))); |
---|
103 | case 'unix' |
---|
104 | s = sub_setfield(s,arg{:},unix(get(tree,uid,'value'))); |
---|
105 | case 'dos' |
---|
106 | s = sub_setfield(s,arg{:},dos(get(tree,uid,'value'))); |
---|
107 | case 'system' |
---|
108 | s = sub_setfield(s,arg{:},system(get(tree,uid,'value'))); |
---|
109 | otherwise |
---|
110 | try, |
---|
111 | s = sub_setfield(s,arg{:},feval(app,get(tree,uid,'value'))); |
---|
112 | catch, |
---|
113 | warning('[XMLTREE] Unknown target application'); |
---|
114 | end |
---|
115 | end |
---|
116 | case 'comment' |
---|
117 | % Comments are forgotten |
---|
118 | otherwise |
---|
119 | warning(sprintf('Type %s unknown : not saved',get(tree,uid,'type'))); |
---|
120 | end |
---|
121 | |
---|
122 | %======================================================================= |
---|
123 | function s = sub_setfield(s,varargin) |
---|
124 | % Same as setfield but using '{}' rather than '()' |
---|
125 | %if (isempty(varargin) | length(varargin) < 2) |
---|
126 | % error('Not enough input arguments.'); |
---|
127 | %end |
---|
128 | |
---|
129 | subs = varargin(1:end-1); |
---|
130 | for i = 1:length(varargin)-1 |
---|
131 | if (isa(varargin{i}, 'cell')) |
---|
132 | types{i} = '{}'; |
---|
133 | elseif isstr(varargin{i}) |
---|
134 | types{i} = '.'; |
---|
135 | subs{i} = varargin{i}; %strrep(varargin{i},' ',''); % deblank field name |
---|
136 | else |
---|
137 | error('Inputs must be either cell arrays or strings.'); |
---|
138 | end |
---|
139 | end |
---|
140 | |
---|
141 | % Perform assignment |
---|
142 | try |
---|
143 | s = builtin('subsasgn', s, struct('type',types,'subs',subs), varargin{end}); |
---|
144 | catch |
---|
145 | error(lasterr) |
---|
146 | end |
---|