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

Last change on this file since 728 was 723, checked in by sommeria, 11 years ago

xmltree and toolbox_calib added to svn

File size: 3.8 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                case 'chardata'
78                        s = sub_setfield(s,arg{:},get(tree,uid,'value'));
79                case 'cdata'
80                        s = sub_setfield(s,arg{:},get(tree,uid,'value'));
81                case 'pi'
82                        % Processing instructions are evaluated if possible
83                        app = get(tree,uid,'target');
84                        switch app
85                                case {'matlab',''}
86                                        s = sub_setfield(s,arg{:},eval(get(tree,uid,'value')));
87                                case 'unix'
88                                        s = sub_setfield(s,arg{:},unix(get(tree,uid,'value')));
89                                case 'dos'
90                                        s = sub_setfield(s,arg{:},dos(get(tree,uid,'value')));
91                                case 'system'
92                                        s = sub_setfield(s,arg{:},system(get(tree,uid,'value')));
93                                otherwise
94                                        try,
95                                                s = sub_setfield(s,arg{:},feval(app,get(tree,uid,'value')));
96                                        catch,
97                                                warning('[Xmltree/convert] Unknown target application');
98                                        end
99                        end
100                case 'comment'
101                        % Comments are forgotten
102                otherwise
103                        warning(sprintf('Type %s unknown : not saved',get(tree,uid,'type')));
104        end
105       
106%=======================================================================
107function s = sub_setfield(s,varargin)
108% Same as setfield but using '{}' rather than '()'
109%if (isempty(varargin) | length(varargin) < 2)
110%    error('Not enough input arguments.');
111%end
112
113subs = varargin(1:end-1);
114for i = 1:length(varargin)-1
115    if (isa(varargin{i}, 'cell'))
116        types{i} = '{}';
117    elseif isstr(varargin{i})
118        types{i} = '.';
119        subs{i} = varargin{i}; %strrep(varargin{i},' ',''); % deblank field name
120    else
121        error('Inputs must be either cell arrays or strings.');
122    end
123end
124
125% Perform assignment
126try
127   s = builtin('subsasgn', s, struct('type',types,'subs',subs), varargin{end});
128catch
129   error(lasterr)
130end
Note: See TracBrowser for help on using the repository browser.