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