source: trunk/src/@xmltree/convert.m @ 849

Last change on this file since 849 was 821, checked in by sommeria, 10 years ago

xmltree_updated

File size: 4.7 KB
Line 
1function 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
23error(nargchk(1,2,nargin));
24
25% Get the root uid of the output structure
26if nargin == 1
27        % Get the root uid of the XML tree
28        root_uid = root(tree);
29else
30        % Uid provided by user
31        root_uid = uid;
32end
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([])
38s = struct('deletedummy','');
39
40%s = sub_convert(tree,s,root_uid,{get(tree,root_uid,'name')});
41s = sub_convert(tree,s,root_uid,{});
42
43s = rmfield(s,'deletedummy');
44
45%=======================================================================
46function 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%=======================================================================
123function 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
129subs = varargin(1:end-1);
130for 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
139end
140
141% Perform assignment
142try
143   s = builtin('subsasgn', s, struct('type',types,'subs',subs), varargin{end});
144catch
145   error(lasterr)
146end
Note: See TracBrowser for help on using the repository browser.