Changeset 925 for trunk/src/@xmltree/find.m
- Timestamp:
- Feb 17, 2016, 12:52:48 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/@xmltree/find.m
r723 r925 16 16 % XML Path Language XPath (http://www.w3.org/TR/xpath) 17 17 % Example: /element1//element2[1]/element3[5]/element4 18 %_______________________________________________________________________ 18 %__________________________________________________________________________ 19 19 % 20 20 % Find elements in an XML tree with specified characteristics or given 21 21 % a path (using a subset of XPath language). 22 %_______________________________________________________________________ 23 % @(#)find.m Guillaume Flandin 01/10/29 22 %__________________________________________________________________________ 23 % Copyright (C) 2002-2011 http://www.artefact.tk/ 24 25 % Guillaume Flandin 26 % $Id: find.m 4460 2011-09-05 14:52:16Z guillaume $ 24 27 25 28 % TODO: … … 30 33 31 34 if nargin==0 32 35 error('[XMLTree] A tree must be provided'); 33 36 elseif nargin==1 34 35 37 list = 1:length(tree.tree); 38 return 36 39 elseif mod(nargin,2) 37 list = sub_find_subtree1(varargin{1}.tree,root(tree),varargin{2:end});38 elseif isa(varargin{2},'double') & ...39 ndims(varargin{2}) == 2& ...40 41 42 elseif nargin==2 & ischar(varargin{2})43 40 list = sub_find_subtree1(varargin{1}.tree,root(varargin{1}),varargin{2:end}); 41 elseif isa(varargin{2},'double') && ... 42 ndims(varargin{2}) == 2 && ... 43 min(size(varargin{2})) == 1 44 list = unique(sub_find_subtree1(varargin{1}.tree,varargin{2:end})); 45 elseif nargin==2 && ischar(varargin{2}) 46 list = sub_pathfinder(varargin{:}); 44 47 else 45 48 error('[XMLTree] Arguments must be parameter/value pairs.'); 46 49 end 47 50 48 %======================================================================= 51 %========================================================================== 49 52 function list = sub_find_subtree1(varargin) 50 51 52 53 54 55 53 list = []; 54 for i=1:length(varargin{2}) 55 res = sub_find_subtree2(varargin{1},... 56 varargin{2}(i),varargin{3:end}); 57 list = [list res]; 58 end 56 59 57 %======================================================================= 60 %========================================================================== 58 61 function list = sub_find_subtree2(varargin) 59 60 61 62 63 64 65 66 67 62 uid = varargin{2}; 63 list = []; 64 if sub_comp_element(varargin{1}{uid},varargin{3:end}) 65 list = [list varargin{1}{uid}.uid]; 66 end 67 if isfield(varargin{1}{uid},'contents') 68 list = [list sub_find_subtree1(varargin{1},... 69 varargin{1}{uid}.contents,varargin{3:end})]; 70 end 68 71 69 %======================================================================= 72 %========================================================================== 70 73 function match = sub_comp_element(varargin) 71 74 match = 0; 72 try ,73 74 75 76 77 78 79 80 catch ,75 try 76 % v = getfield(varargin{1}, varargin{2}); % slow... 77 for i=1:floor(nargin/2) 78 v = subsref(varargin{1}, struct('type','.','subs',varargin{i+1})); 79 if strcmp(v,varargin{i+2}) 80 match = 1; 81 end 82 end 83 catch 81 84 end 82 85 … … 85 88 %for i=1:length(floor(nargin/2)) % bug: remove length !!! 86 89 % if isfield(varargin{1},varargin{i+1}) 87 % 88 % 89 % 90 % 91 % 92 % 93 % 94 % 95 % 96 % 97 % 98 % 90 % if ischar(getfield(varargin{1},varargin{i+1})) & ischar(varargin{i+2}) 91 % if strcmp(getfield(varargin{1},varargin{i+1}),char(varargin{i+2})) 92 % match = 1; 93 % end 94 % elseif isa(getfield(varargin{1},varargin{i+1}),'double') & ... 95 % isa(varargin{i+2},'double') 96 % if getfield(varargin{1},varargin{i+1}) == varargin{i+2} 97 % match = 1; 98 % end 99 % else 100 % warning('Cannot compare different objects'); 101 % end 99 102 % end 100 103 %end 101 104 102 %======================================================================= 105 %========================================================================== 103 106 function list = sub_pathfinder(tree,pth) 104 105 i = findstr(pth,'/');106 107 108 109 110 111 112 if j<length(i)& i(j+1)==i(j)+1113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 if val < 1| val > length(list)+1151 152 153 154 155 156 157 158 159 160 161 162 %======================================================================= 107 %- Search for the delimiter '/' in the path 108 i = strfind(pth,'/'); 109 %- Begin search by root 110 list = root(tree); 111 %- Walk through the tree 112 j = 1; 113 while j <= length(i) 114 %- Look for recursion '//' 115 if j<length(i) && i(j+1)==i(j)+1 116 recursive = 1; 117 j = j + 1; 118 else 119 recursive = 0; 120 end 121 %- Catch the current tag 'element[x]' 122 if j ~= length(i) 123 element = pth(i(j)+1:i(j+1)-1); 124 else 125 element = pth(i(j)+1:end); 126 end 127 %- Search for [] brackets 128 k = xml_findstr(element,'[',1,1); 129 %- If brackets are present in current element 130 if ~isempty(k) 131 l = xml_findstr(element,']',1,1); 132 val = str2num(element(k+1:l-1)); 133 element = element(1:k-1); 134 end 135 %- Use recursivity 136 if recursive 137 list = find(tree,list,'name',element); 138 %- Just look at children 139 else 140 if i(j)==1 % if '/root/...' (list = root(tree) in that case) 141 if sub_comp_element(tree.tree{list},'name',element) 142 % list = 1; % list still contains root(tree) 143 else 144 list = []; 145 return; 146 end 147 else 148 list = sub_findchild(tree,list,element); 149 end 150 end 151 % If an element is specified using a key 152 if ~isempty(k) 153 if val < 1 || val > length(list)+1 154 error('[XMLTree] Bad key in the path.'); 155 elseif val == length(list)+1 156 list = []; 157 return; 158 end 159 list = list(val); 160 end 161 if isempty(list), return; end 162 j = j + 1; 163 end 164 165 %========================================================================== 163 166 function list = sub_findchild(tree,listt,elmt) 164 165 166 167 168 169 170 171 167 list = []; 168 for a=1:length(listt) 169 for b=1:length(tree.tree{listt(a)}.contents) 170 if sub_comp_element(tree.tree{tree.tree{listt(a)}.contents(b)},'name',elmt) 171 list = [list tree.tree{tree.tree{listt(a)}.contents(b)}.uid]; 172 end 173 end 174 end
Note: See TracChangeset
for help on using the changeset viewer.