Ignore:
Timestamp:
Feb 17, 2016, 12:52:48 PM (8 years ago)
Author:
sommeria
Message:

xmltree updated

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/@xmltree/find.m

    r723 r925  
    1616%        XML Path Language XPath (http://www.w3.org/TR/xpath)
    1717% Example: /element1//element2[1]/element3[5]/element4
    18 %_______________________________________________________________________
     18%__________________________________________________________________________
    1919%
    2020% Find elements in an XML tree with specified characteristics or given
    2121% 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 $
    2427
    2528% TODO:
     
    3033
    3134if nargin==0
    32         error('[XMLTree] A tree must be provided');
     35    error('[XMLTree] A tree must be provided');
    3336elseif nargin==1
    34         list = 1:length(tree.tree);
    35         return
     37    list = 1:length(tree.tree);
     38    return
    3639elseif 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            min(size(varargin{2})) == 1
    41         list = unique(sub_find_subtree1(varargin{1}.tree,varargin{2:end}));
    42 elseif nargin==2 & ischar(varargin{2})
    43         list = sub_pathfinder(varargin{:});
     40    list = sub_find_subtree1(varargin{1}.tree,root(varargin{1}),varargin{2:end});
     41elseif 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}));
     45elseif nargin==2 && ischar(varargin{2})
     46    list = sub_pathfinder(varargin{:});
    4447else
    4548   error('[XMLTree] Arguments must be parameter/value pairs.');
    4649end
    4750
    48 %=======================================================================
     51%==========================================================================
    4952function list = sub_find_subtree1(varargin)
    50         list = [];
    51         for i=1:length(varargin{2})
    52                 res = sub_find_subtree2(varargin{1},...
    53                                 varargin{2}(i),varargin{3:end});
    54                 list = [list res];
    55         end
     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
    5659
    57 %=======================================================================
     60%==========================================================================
    5861function list = sub_find_subtree2(varargin)
    59         uid = varargin{2};
    60         list = [];
    61         if sub_comp_element(varargin{1}{uid},varargin{3:end})
    62                 list = [list varargin{1}{uid}.uid];
    63         end
    64         if isfield(varargin{1}{uid},'contents')
    65                 list = [list sub_find_subtree1(varargin{1},...
    66                         varargin{1}{uid}.contents,varargin{3:end})];
    67         end
     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
    6871
    69 %=======================================================================
     72%==========================================================================
    7073function match = sub_comp_element(varargin)
    7174match = 0;
    72 try,
    73         % v = getfield(varargin{1}, varargin{2}); % slow...
    74         for i=1:floor(nargin/2)
    75                 v = subsref(varargin{1}, struct('type','.','subs',varargin{i+1}));     
    76                 if strcmp(v,varargin{i+2})
    77                         match = 1;
    78                 end
    79         end
    80 catch,
     75try
     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
     83catch
    8184end
    8285
     
    8588%for i=1:length(floor(nargin/2)) % bug: remove length !!!
    8689%   if isfield(varargin{1},varargin{i+1})
    87 %         if ischar(getfield(varargin{1},varargin{i+1})) & ischar(varargin{i+2})
    88 %          if strcmp(getfield(varargin{1},varargin{i+1}),char(varargin{i+2}))
    89 %                       match = 1;
    90 %                end
    91 %         elseif isa(getfield(varargin{1},varargin{i+1}),'double') & ...
    92 %                       isa(varargin{i+2},'double')
    93 %                if getfield(varargin{1},varargin{i+1}) == varargin{i+2}
    94 %                       match = 1;
    95 %               end
    96 %        else
    97 %               warning('Cannot compare different objects');
    98 %         end
     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
    99102%   end
    100103%end
    101104
    102 %=======================================================================
     105%==========================================================================
    103106function list = sub_pathfinder(tree,pth)
    104         %- Search for the delimiter '/' in the path
    105         i = findstr(pth,'/');
    106         %- Begin search by root
    107         list = root(tree);
    108         %- Walk through the tree
    109         j = 1;
    110         while j <= length(i)
    111                 %- Look for recursion '//'
    112                 if j<length(i) & i(j+1)==i(j)+1
    113                         recursive = 1;
    114                         j = j + 1;
    115                 else
    116                         recursive = 0;
    117                 end
    118                 %- Catch the current tag 'element[x]'
    119                 if j ~= length(i)
    120                         element = pth(i(j)+1:i(j+1)-1);
    121                 else
    122                         element = pth(i(j)+1:end);
    123                 end
    124                 %- Search for [] brackets
    125                 k = xml_findstr(element,'[',1,1);
    126                 %- If brackets are present in current element
    127                 if ~isempty(k)
    128                         l   = xml_findstr(element,']',1,1);
    129                         val = str2num(element(k+1:l-1));
    130                         element = element(1:k-1);
    131                 end
    132                 %- Use recursivity
    133                 if recursive
    134                         list = find(tree,list,'name',element);
    135                 %- Just look at children
    136                 else
    137                         if i(j)==1 % if '/root/...' (list = root(tree) in that case)
    138                                 if sub_comp_element(tree.tree{list},'name',element)
    139                                         % list = 1; % list still contains root(tree)
    140                                 else
    141                                         list = [];
    142                                         return;
    143                                 end
    144                         else
    145                                 list = sub_findchild(tree,list,element);
    146                         end
    147                 end
    148                 % If an element is specified using a key
    149                 if ~isempty(k)
    150                         if val < 1 | val > length(list)+1
    151                                 error('[XMLTree] Bad key in the path.');
    152                         elseif val == length(list)+1
    153                                 list = [];
    154                                 return;
    155                         end
    156                         list = list(val);
    157                 end
    158                 if isempty(list), return; end
    159                 j = j + 1;
    160         end
    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%==========================================================================
    163166function list = sub_findchild(tree,listt,elmt)
    164         list = [];
    165         for a=1:length(listt)
    166                 for b=1:length(tree.tree{listt(a)}.contents)
    167                         if sub_comp_element(tree.tree{tree.tree{listt(a)}.contents(b)},'name',elmt)
    168                                 list = [list tree.tree{tree.tree{listt(a)}.contents(b)}.uid];
    169                         end
    170                 end
    171         end
     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.