[925] | 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
|
---|