[723] | 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 | 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 | %======================================================================= |
---|
| 107 | function 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 | |
---|
| 113 | subs = varargin(1:end-1); |
---|
| 114 | for 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 |
---|
| 123 | end |
---|
| 124 | |
---|
| 125 | % Perform assignment |
---|
| 126 | try |
---|
| 127 | s = builtin('subsasgn', s, struct('type',types,'subs',subs), varargin{end}); |
---|
| 128 | catch |
---|
| 129 | error(lasterr) |
---|
| 130 | end |
---|