1. 程式人生 > >Matlab: 深度學習目標檢測xml標註資訊批量統計

Matlab: 深度學習目標檢測xml標註資訊批量統計

"""

https://blog.csdn.net/gusui7202/article/details/83239142

qhy。

"""

程式1:xml_read()   #xml讀取  

程式2:mian() #xml內容統計

使用:將兩個程式放入同一個資料夾下,修改路徑即可。要統計不同的資訊,修改main函式就行。

我主要統計的是資料集中每一類標籤的框數量。

程式1: 資料讀取模組

function [tree, RootName, DOMnode] = xml_read(xmlfile, Pref)
%XML_READ reads xml files and converts them into Matlab's struct tree.
%
% DESCRIPTION
% tree = xml_read(xmlfile) reads 'xmlfile' into data structure 'tree'
%
% tree = xml_read(xmlfile, Pref) reads 'xmlfile' into data structure 'tree'
% according to your preferences
%
% [tree, RootName, DOMnode] = xml_read(xmlfile) get additional information
% about XML file
%
% INPUT:
%  xmlfile    URL or filename of xml file to read
%  Pref     Preferences:
%    Pref.ItemName - default 'item' - name of a special tag used to itemize
%                    cell arrays
%    Pref.ReadAttr - default true - allow reading attributes
%    Pref.ReadSpec - default true - allow reading special nodes
%    Pref.Str2Num  - default 'smart' - convert strings that look like numbers
%                   to numbers. Options: "always", "never", and "smart"
%    Pref.KeepNS   - default true - keep or strip namespace info
%    Pref.NoCells  - default true - force output to have no cell arrays
%    Pref.Debug    - default false - show mode specific error messages
%    Pref.NumLevels- default infinity - how many recursive levels are
%      allowed. Can be used to speed up the function by prunning the tree.
%    Pref.RootOnly - default true - output variable 'tree' corresponds to
%      xml file root element, otherwise it correspond to the whole file.
%    Pref.CellItem - default 'true' - leave 'item' nodes in cell notation.
% OUTPUT:
%  tree         tree of structs and/or cell arrays corresponding to xml file
%  RootName     XML tag name used for root (top level) node.
%               Optionally it can be a string cell array storing: Name of
%               root node, document "Processing Instructions" data and
%               document "comment" string
%  DOMnode      output of xmlread
%
% DETAILS:
% Function xml_read first calls MATLAB's xmlread function and than
% converts its output ('Document Object Model' tree of Java objects)
% to tree of MATLAB struct's. The output is in format of nested structs
% and cells. In the output data structure field names are based on
% XML tags, except in cases when tags produce illegal variable names.
%
% Several special xml node types result in special tags for fields of
% 'tree' nodes:
%  - node.CONTENT - stores data section of the node if other fields are
%    present. Usually data section is stored directly in 'node'.
%  - node.ATTRIBUTE.name - stores node's attribute called 'name'.
%  - node.COMMENT - stores node's comment section (string). For global
%    comments see "RootName" output variable.
%  - node.CDATA_SECTION - stores node's CDATA section (string).
%  - node.PROCESSING_INSTRUCTIONS - stores "processing instruction" child
%    node. For global "processing instructions" see "RootName" output variable.
%  - other special node types like: document fragment nodes, document type
%   nodes, entity nodes, notation nodes and processing instruction nodes
%   will be treated like regular nodes
%
% EXAMPLES:
%   MyTree=[];
%   MyTree.MyNumber = 13;
%   MyTree.MyString = 'Hello World';
%   xml_write('test.xml', MyTree);
%   [tree treeName] = xml_read ('test.xml');
%   disp(treeName)
%   gen_object_display()
%   % See also xml_examples.m
%
% See also:
%   xml_write, xmlread, xmlwrite
%
% Written by Jarek Tuszynski, SAIC, jaroslaw.w.tuszynski_at_saic.com
% References:
%  - Function inspired by Example 3 found in xmlread function.
%  - Output data structures inspired by xml_toolbox structures.

%% 預設設定
DPref.TableName  = {'tr','td'}; % name of a special tags used to itemize 2D cell arrays
DPref.ItemName  = 'item'; % name of a special tag used to itemize 1D cell arrays
DPref.CellItem  = false;  % leave 'item' nodes in cell notation
DPref.ReadAttr  = true;   % allow reading attributes
DPref.ReadSpec  = true;   % allow reading special nodes: comments, CData, etc.
DPref.KeepNS    = true;   % Keep or strip namespace info
DPref.Str2Num   = 'smart';% convert strings that look like numbers to numbers
DPref.NoCells   = true;   % force output to have no cell arrays
DPref.NumLevels = 1e10;   % number of recurence levels
DPref.PreserveSpace = false; % Preserve or delete spaces at the beggining and the end of stings?
RootOnly        = true;   % return root node  with no top level special nodes
Debug           = false;  % show specific errors (true) or general (false)?
tree            = [];
RootName        = [];

%% 檢查matlab版本
v = ver('MATLAB');
version = str2double(regexp(v.Version, '\d.\d','match','once'));
if (version<7.1)
  error('Your MATLAB version is too old. You need version 7.1 or newer.');
end

%%讀取配置引數
if (nargin>1)
  if (isfield(Pref, 'TableName')), DPref.TableName = Pref.TableName; end
  if (isfield(Pref, 'ItemName' )), DPref.ItemName  = Pref.ItemName;  end
  if (isfield(Pref, 'CellItem' )), DPref.CellItem  = Pref.CellItem;  end
  if (isfield(Pref, 'Str2Num'  )), DPref.Str2Num   = Pref.Str2Num ;  end
  if (isfield(Pref, 'NoCells'  )), DPref.NoCells   = Pref.NoCells ;  end
  if (isfield(Pref, 'NumLevels')), DPref.NumLevels = Pref.NumLevels; end
  if (isfield(Pref, 'ReadAttr' )), DPref.ReadAttr  = Pref.ReadAttr;  end
  if (isfield(Pref, 'ReadSpec' )), DPref.ReadSpec  = Pref.ReadSpec;  end
  if (isfield(Pref, 'KeepNS'   )), DPref.KeepNS    = Pref.KeepNS;    end
  if (isfield(Pref, 'RootOnly' )), RootOnly        = Pref.RootOnly;  end
  if (isfield(Pref, 'Debug'    )), Debug           = Pref.Debug   ;  end
  if (isfield(Pref, 'PreserveSpace')), DPref.PreserveSpace = Pref.PreserveSpace; end
end
if ischar(DPref.Str2Num), % convert from character description to numbers
  DPref.Str2Num = find(strcmpi(DPref.Str2Num, {'never', 'smart', 'always'}))-1;
  if isempty(DPref.Str2Num), DPref.Str2Num=1; end % 1-smart by default
end

%% 讀取xml
if isa(xmlfile, 'org.apache.xerces.dom.DeferredDocumentImpl');
  % if xmlfile is a DOMnode than skip the call to xmlread
  try
    try    # try-catch主要用來查詢使用者裡面的錯誤,或者可以判斷是否存在變數的使用
      DOMnode = xmlfile;
    catch ME
      error('Invalid DOM node: \n%s.', getReport(ME));
    end
  catch %#ok<CTCH> catch for mablab versions prior to 7.5
    error('Invalid DOM node. \n');
  end
else         % we assume xmlfile is a filename
  if (Debug) % in debuging mode crashes are allowed
    DOMnode = xmlread(xmlfile);
  else       % in normal mode crashes are not allowed
    try
      try
        DOMnode = xmlread(xmlfile);  #matlab自帶xml讀取函式
      catch ME
        error('Failed to read XML file %s: \n%s',xmlfile, getReport(ME));
      end
    catch %#ok<CTCH> catch for mablab versions prior to 7.5
      error('Failed to read XML file %s\n',xmlfile);
    end
  end
end
Node = DOMnode.getFirstChild;

%%找到根節點,同時儲存全域性變數和正在處理的資料 

Find the Root node. Also store data from Global Comment and Processing
%  Instruction nodes, if any.
GlobalTextNodes = cell(1,3);
GlobalProcInst  = [];
GlobalComment   = [];
GlobalDocType   = [];
while (~isempty(Node))  #節點非空
  if (Node.getNodeType==Node.ELEMENT_NODE) #判斷跟節點
    RootNode=Node;
  elseif (Node.getNodeType==Node.PROCESSING_INSTRUCTION_NODE)
    data   = strtrim(char(Node.getData));
    target = strtrim(char(Node.getTarget));
    GlobalProcInst = [target, ' ', data];
    GlobalTextNodes{2} = GlobalProcInst;
  elseif (Node.getNodeType==Node.COMMENT_NODE)
    GlobalComment = strtrim(char(Node.getData));
    GlobalTextNodes{3} = GlobalComment;
    %   elseif (Node.getNodeType==Node.DOCUMENT_TYPE_NODE)
    %     GlobalTextNodes{4} = GlobalDocType;
  end
  Node = Node.getNextSibling;
end

%% parse xml file through calls to recursive DOMnode2struct function
if (Debug)   % in debuging mode crashes are allowed
  [tree RootName] = DOMnode2struct(RootNode, DPref, 1);
else         % in normal mode crashes are not allowed
  try
    try
      [tree RootName] = DOMnode2struct(RootNode, DPref, 1);
    catch ME
      error('Unable to parse XML file %s: \n %s.',xmlfile, getReport(ME));  #捕捉異常錯誤並顯示
    end
  catch %#ok<CTCH> catch for mablab versions prior to 7.5
    error('Unable to parse XML file %s.',xmlfile);
  end
end

%% If there were any Global Text nodes than return them
if (~RootOnly)
  if (~isempty(GlobalProcInst) && DPref.ReadSpec)
    t.PROCESSING_INSTRUCTION = GlobalProcInst;
  end
  if (~isempty(GlobalComment) && DPref.ReadSpec)
    t.COMMENT = GlobalComment;
  end
  if (~isempty(GlobalDocType) && DPref.ReadSpec)
    t.DOCUMENT_TYPE = GlobalDocType;
  end
  t.(RootName) = tree;
  tree=t;
end
if (~isempty(GlobalTextNodes))
  GlobalTextNodes{1} = RootName;
  RootName = GlobalTextNodes;
end


%% =======================================================================
%  === DOMnode2struct Function ===========================================
%  =======================================================================
function [s TagName LeafNode] = DOMnode2struct(node, Pref, level)

%% === Step 1: Get node name and check if it is a leaf node ==============獲取節點名,檢查是否為葉節點
[TagName LeafNode] = NodeName(node, Pref.KeepNS);
s = []; % initialize output structure

%% === Step 2: Process Leaf Nodes (nodes with no children) ===============如果是葉節點進行處理
if (LeafNode)
  if (LeafNode>1 && ~Pref.ReadSpec), LeafNode=-1; end % tags only so ignore special nodes
  if (LeafNode>0) % supported leaf node types
    try
      try         % use try-catch: errors here are often due to VERY large fields (like images) that overflow java memory
        s = char(node.getData);
        if (isempty(s)), s = ' '; end                              % make it a string
        % for some reason current xmlread 'creates' a lot of empty text
        % fields with first chatacter=10 - those will be deleted.
        if (~Pref.PreserveSpace || s(1)==10) 
          if (isspace(s(1)) || isspace(s(end))), s = strtrim(s); end % trim speces is any
        end
        if (LeafNode==1), s=str2var(s, Pref.Str2Num, 0); end       % convert to number(s) if needed
      catch ME    % catch for mablab versions 7.5 and higher
        warning('xml_io_tools:read:LeafRead', ...
          'This leaf node could not be read and was ignored. ');
        getReport(ME)
      end
    catch         %#ok<CTCH> catch for mablab versions prior to 7.5
      warning('xml_io_tools:read:LeafRead', ...
        'This leaf node could not be read and was ignored. ');
    end
  end
  if (LeafNode==3) % ProcessingInstructions need special treatment
    target = strtrim(char(node.getTarget));
    s = [target, ' ', s];
  end
  return % We are done the rest of the function deals with nodes with children
end
if (level>Pref.NumLevels+1), return; end % if Pref.NumLevels is reached than we are done

%% === Step 3: Process nodes with children ===============================#有子類節點進行處理
if (node.hasChildNodes)        % children present
  Child  = node.getChildNodes; % create array of children nodes
  nChild = Child.getLength;    % number of children
  
  % --- pass 1: how many children with each name -----------------------1、獲取子節點 名字、數量
  f = [];
  for iChild = 1:nChild        % read in each child
    [cname cLeaf] = NodeName(Child.item(iChild-1), Pref.KeepNS);
    if (cLeaf<0), continue; end % unsupported leaf node types
    if (~isfield(f,cname)),
      f.(cname)=0;           % initialize first time I see this name
    end
    f.(cname) = f.(cname)+1; % add to the counter
  end                        % end for iChild
  % text_nodes become CONTENT & for some reason current xmlread 'creates' a
  % lot of empty text fields so f.CONTENT value should not be trusted
  if (isfield(f,'CONTENT') && f.CONTENT>2), f.CONTENT=2; end
  
  % --- pass 2: store all the children as struct of cell arrays ---------- 以matlab的cell陣列結構來儲存子所有子節點
  for iChild = 1:nChild        % read in each child
    [c cname cLeaf] = DOMnode2struct(Child.item(iChild-1), Pref, level+1);
    if (cLeaf && isempty(c))   % if empty leaf node than skip
      continue;                % usually empty text node or one of unhandled node types
    elseif (nChild==1 && cLeaf==1)
      s=c;                     % shortcut for a common case
    else                       % if normal node
      if (level>Pref.NumLevels), continue; end
      n = f.(cname);           % how many of them in the array so far?
      if (~isfield(s,cname))   % encountered this name for the first time
        if (n==1)              % if there will be only one of them ...
          s.(cname) = c;       % than save it in format it came in
        else                   % if there will be many of them ...
          s.(cname) = cell(1,n);
          s.(cname){1} = c;    % than save as cell array
        end
        f.(cname) = 1;         % initialize the counter
      else                     % already have seen this name
        s.(cname){n+1} = c;    % add to the array
        f.(cname) = n+1;       % add to the array counter
      end
    end
  end   % for iChild
end % end if (node.hasChildNodes)

%% === Step 4: Post-process struct's created for nodes with children =====處理有子節點的節點結構
if (isstruct(s))
  fields = fieldnames(s);   #獲取名字
  nField = length(fields);   #獲取子節點數量
  
  % Detect structure that looks like Html table and store it in cell Matrix #檢測html結構資料並且以cell儲存
  if (nField==1 && strcmpi(fields{1},Pref.TableName{1}))
    tr = s.(Pref.TableName{1});
    fields2 = fieldnames(tr{1});
    if (length(fields2)==1 && strcmpi(fields2{1},Pref.TableName{2}))
      % This seems to be a special structure such that for 
      % Pref.TableName = {'tr','td'} 's' corresponds to 
      %    <tr> <td>M11</td> <td>M12</td> </tr>
      %    <tr> <td>M12</td> <td>M22</td> </tr>
      % Recognize it as encoding for 2D struct
      nr = length(tr);
      for r = 1:nr
        row = tr{r}.(Pref.TableName{2});
        Table(r,1:length(row)) = row; %#ok<AGROW>
      end
      s = Table;
    end
  end

  % --- Post-processing: convert 'struct of cell-arrays' to 'array of structs'
  % Example: let say s has 3 fields s.a, s.b & s.c  and each field is an
  % cell-array with more than one cell-element and all 3 have the same length.
  % Then change it to array of structs, each with single cell.
  % This way element s.a{1} will be now accessed through s(1).a
  vec = zeros(size(fields));
  for i=1:nField, vec(i) = f.(fields{i}); end
  if (numel(vec)>1 && vec(1)>1 && var(vec)==0)  % convert from struct of
    s = cell2struct(struct2cell(s), fields, 1); % arrays to array of struct
  end % if anyone knows better way to do above conversion please let me know.

end

%% === Step 5: Process nodes with attributes =============================
if (node.hasAttributes && Pref.ReadAttr)
  if (~isstruct(s)),              % make into struct if is not already
    ss.CONTENT=s;
    s=ss;
  end
  Attr  = node.getAttributes;     % list of all attributes
  for iAttr = 1:Attr.getLength    % for each attribute
    name  = char(Attr.item(iAttr-1).getName);  % attribute name
    name  = str2varName(name, Pref.KeepNS);    % fix name if needed
    value = char(Attr.item(iAttr-1).getValue); % attribute value
    value = str2var(value, Pref.Str2Num, 1);   % convert to number if possible
    s.ATTRIBUTE.(name) = value;   % save again
  end                             % end iAttr loop
end % done with attributes
if (~isstruct(s)), return; end %The rest of the code deals with struct's

%% === Post-processing: fields of "s"
% convert  'cell-array of structs' to 'arrays of structs'
fields = fieldnames(s);     % get field names
nField = length(fields);
for iItem=1:length(s)       % for each struct in the array - usually one
  for iField=1:length(fields)
    field = fields{iField}; % get field name
    % if this is an 'item' field and user want to leave those as cells
    % than skip this one
    if (strcmpi(field, Pref.ItemName) && Pref.CellItem), continue; end
    x = s(iItem).(field);
    if (iscell(x) && all(cellfun(@isstruct,x(:))) && numel(x)>1) % it's cell-array of structs
      % numel(x)>1 check is to keep 1 cell-arrays created when Pref.CellItem=1
      try                           % this operation fails sometimes
        % example: change s(1).a{1}.b='jack'; s(1).a{2}.b='john'; to
        % more convinient s(1).a(1).b='jack'; s(1).a(2).b='john';
        s(iItem).(field) = [x{:}]';  %#ok<AGROW> % converted to arrays of structs
      catch %#ok<CTCH>
        % above operation will fail if s(1).a{1} and s(1).a{2} have
        % different fields. If desired, function forceCell2Struct can force
        % them to the same field structure by adding empty fields.
        if (Pref.NoCells)
          s(iItem).(field) = forceCell2Struct(x); %#ok<AGROW>
        end
      end % end catch
    end
  end
end

%% === Step 4: Post-process struct's created for nodes with children =====

% --- Post-processing: remove special 'item' tags ---------------------
% many xml writes (including xml_write) use a special keyword to mark
% arrays of nodes (see xml_write for examples). The code below converts
% s.item to s.CONTENT
ItemContent = false;
if (isfield(s,Pref.ItemName))
  s.CONTENT = s.(Pref.ItemName);
  s = rmfield(s,Pref.ItemName);
  ItemContent = Pref.CellItem; % if CellItem than keep s.CONTENT as cells
end

% --- Post-processing: clean up CONTENT tags ---------------------
% if s.CONTENT is a cell-array with empty elements at the end than trim
% the length of this cell-array. Also if s.CONTENT is the only field than
% remove .CONTENT part and store it as s.
if (isfield(s,'CONTENT'))
  if (iscell(s.CONTENT) && isvector(s.CONTENT))
    x = s.CONTENT;
    for i=numel(x):-1:1, if ~isempty(x{i}), break; end; end
    if (i==1 && ~ItemContent)
      s.CONTENT = x{1};   % delete cell structure
    else
      s.CONTENT = x(1:i); % delete empty cells
    end
  end
  if (nField==1)
    if (ItemContent)
      ss = s.CONTENT;       % only child: remove a level but ensure output is a cell-array
      s=[]; s{1}=ss;
    else
      s = s.CONTENT;        % only child: remove a level
    end
  end
end

%% =======================================================================
%  === forceCell2Struct Function =========================================
%  =======================================================================
function s = forceCell2Struct(x)
% Convert cell-array of structs, where not all of structs have the same
% fields, to a single array of structs

%% Convert 1D cell array of structs to 2D cell array, where each row
% represents item in original array and each column corresponds to a unique
% field name. Array "AllFields" store fieldnames for each column
AllFields = fieldnames(x{1});     % get field names of the first struct
CellMat = cell(length(x), length(AllFields));
for iItem=1:length(x)
  fields = fieldnames(x{iItem});  % get field names of the next struct
  for iField=1:length(fields)     % inspect all fieldnames and find those
    field = fields{iField};       % get field name
    col = find(strcmp(field,AllFields),1);
    if isempty(col)               % no column for such fieldname yet
      AllFields = [AllFields; field]; %#ok<AGROW>
      col = length(AllFields);    % create a new column for it
    end
    CellMat{iItem,col} = x{iItem}.(field); % store rearanged data
  end
end
%% Convert 2D cell array to array of structs
s = cell2struct(CellMat, AllFields, 2);

%% =======================================================================
%  === str2var Function ==================================================
%  =======================================================================
function val=str2var(str, option, attribute)
% Can this string 'str' be converted to a number? if so than do it. #字串轉數字型別
val = str;
len = numel(str);
if (len==0    || option==0), return; end % Str2Num="never" of empty string -> do not do enything
if (len>10000 && option==1), return; end % Str2Num="smart" and string is very long -> probably base64 encoded binary
digits = '(Inf)|(NaN)|(pi)|[\t\n\d\+\-\*\.ei EI\[\]\;\,]';
s = regexprep(str, digits, ''); % remove all the digits and other allowed characters
if (~all(~isempty(s)))          % if nothing left than this is probably a number
  if (~isempty(strfind(str, ' '))), option=2; end %if str has white-spaces assume by default that it is not a date string
  if (~isempty(strfind(str, '['))), option=2; end % same with brackets
  str(strfind(str, '\n')) = ';';% parse data tables into 2D arrays, if any
  if (option==1)                % the 'smart' option
    try                         % try to convert to a date, like 2007-12-05
      datenum(str);             % if successful than leave it as string
    catch                       %#ok<CTCH> % if this is not a date than ...
      option=2;                 % ... try converting to a number
    end
  end
  if (option==2)
    if (attribute)
      num = str2double(str);      % try converting to a single number using sscanf function
      if isnan(num), return; end  % So, it wasn't really a number after all    
    else
      num = str2num(str);         %#ok<ST2NM> % try converting to a single number or array using eval function
    end
    if(isnumeric(num) && numel(num)>0), val=num; end % if convertion to a single was succesful than save
  end
elseif ((str(1)=='[' && str(end)==']') || (str(1)=='{' && str(end)=='}')) % this looks like a (cell) array encoded as a string
  try 
    val = eval(str); 
  catch              %#ok<CTCH>
    val = str; 
  end                     
elseif (~attribute)   % see if it is a boolean array with no [] brackets
  str1 = lower(str);
  str1 = strrep(str1, 'false', '0');
  str1 = strrep(str1, 'true' , '1');
  s = regexprep(str1, '[01 \;\,]', ''); % remove all 0/1, spaces, commas and semicolons 
  if (~all(~isempty(s)))          % if nothing left than this is probably a boolean array
    num  = str2num(str1); %#ok<ST2NM>
    if(isnumeric(num) && numel(num)>0), val = (num>0);  end % if convertion was succesful than save as logical
  end
end


%% =======================================================================
%  === str2varName Function ==============================================
%  =======================================================================
function str = str2varName(str, KeepNS)
% convert a sting to a valid matlab variable name
if(KeepNS)
  str = regexprep(str,':','_COLON_', 'once', 'ignorecase');
else
  k = strfind(str,':');
  if (~isempty(k))
    str = str(k+1:end);
  end
end
str = regexprep(str,'-','_DASH_'  ,'once', 'ignorecase');
if (~isvarname(str)) && (~iskeyword(str))
  str = genvarname(str);
end

%% =======================================================================
%  === NodeName Function =================================================
%  =======================================================================
function [Name LeafNode] = NodeName(node, KeepNS)
% get node name and make sure it is a valid variable name in Matlab.
% also get node type:
%   LeafNode=0 - normal element node,
%   LeafNode=1 - text node
%   LeafNode=2 - supported non-text leaf node,
%   LeafNode=3 - supported processing instructions leaf node,
%   LeafNode=-1 - unsupported non-text leaf node
switch (node.getNodeType)
  case node.ELEMENT_NODE
    Name = char(node.getNodeName);% capture name of the node
    Name = str2varName(Name, KeepNS);     % if Name is not a good variable name - fix it
    LeafNode = 0;
  case node.TEXT_NODE
    Name = 'CONTENT';
    LeafNode = 1;
  case node.COMMENT_NODE
    Name = 'COMMENT';
    LeafNode = 2;
  case node.CDATA_SECTION_NODE
    Name = 'CDATA_SECTION';
    LeafNode = 2;
  case node.DOCUMENT_TYPE_NODE
    Name = 'DOCUMENT_TYPE';
    LeafNode = 2;
  case node.PROCESSING_INSTRUCTION_NODE
    Name = 'PROCESSING_INSTRUCTION';
    LeafNode = 3;
  otherwise
    NodeType = {'ELEMENT','ATTRIBUTE','TEXT','CDATA_SECTION', ...
      'ENTITY_REFERENCE', 'ENTITY', 'PROCESSING_INSTRUCTION', 'COMMENT',...
      'DOCUMENT', 'DOCUMENT_TYPE', 'DOCUMENT_FRAGMENT', 'NOTATION'};
    Name = char(node.getNodeName);% capture name of the node
    warning('xml_io_tools:read:unkNode', ...
      'Unknown node type encountered: %s_NODE (%s)', NodeType{node.getNodeType}, Name);
    LeafNode = -1;
end

程式2:主函式

  1. %xml統計程式
  2. %%  讀取每一個子資料夾裡的xml檔案
  3. clc;
  4. clear all;
  5. %主資料夾路徑
  6. maindir = 'D:\1.資料\趙\工作\3.資料庫\標註任務\標註7\資料標註';
  7. % 使用dir函式,獲取指定資料夾下所有子資料夾和檔案,並存放在一種[檔案結構體]陣列中
  8. subdir =  dir( maindir );   
  9. %建立一個統計輸出文字
  10.  fid=fopen('C:\Users\nan\Desktop\output.txt','wt'); 
  11.  %總框數量
  12.  all_boxs_number = 0;
  13. %%懸垂線夾
  14. pre_twisted_suspension_clamp_boxs_number = 0;
  15. bag_type_suspension_clamp_boxs_number = 0;
  16. jumper_suspension_clamp_boxs_number = 0;
  17. %%耐張線夾
  18. bolt_type_strain_clamp_boxs_number = 0;
  19. compression_type_strain_clamp_boxs_number = 0;
  20. wedge_type_strain_clamp_boxs_number = 0;
  21. %%連線金具
  22. hanging_board_boxs_number = 0;
  23. u_type_hanging_ring_boxs_number = 0;
  24. yoke_plate_boxs_number = 0;
  25. %%接續金具
  26. parallel_groove_clamp_boxs_number = 0;
  27. single_slot_wire_clip_boxs_number = 0;
  28. %%防護金具
  29. shockproof_hammer_boxs_number = 0;
  30. spacer_boxs_number = 0;
  31. grading_ring_boxs_number = 0;
  32. shielded_ring_boxs_number = 0;
  33. weight_boxs_number=0;
  34. %%crop類
  35. %%螺栓
  36. normal_bolt_boxs_number = 0;
  37. %螺母
  38. nut_loosening_boxs_number = 0;
  39. nut_losing_boxs_number = 0;
  40. nut_directly_loosening_bolt_boxs_number = 0;
  41. nut_indirectly_loosening_bolt_boxs_number = 0;
  42. %銷子
  43. pin_loosening_boxs_number = 0;
  44. pin_losing_boxs_number = 0;
  45. pin_closing_boxs_number = 0;
  46. visible_pin_losing_boxs_number = 0;
  47. invisible_pin_losing_boxs_number = 0;
  48. %%碗頭
  49. normal_bowl_head_boxs_number = 0;
  50. bowl_head_pin_closing_boxs_number = 0;
  51. bowl_head_pin_loosening_boxs_number = 0;
  52. bowl_head_pin_losing_boxs_number = 0;
  53.  %對每一個子資料夾進行以下操作
  54. for i = 1 : length( subdir )
  55.     if( isequal( subdir( i ).name, '.' ) || ...% ifequal()判斷幾個引數是否相等,相等返回1不等返回0
  56.             isequal( subdir( i ).name, '..' ) || ...
  57.         ~subdir( i ).isdir )   % 如果不是目錄跳過
  58.         continue;
  59.     end
  60.      %fullfile(dir1,dir2,'filename')
  61.     subdirpath = fullfile( maindir, subdir( i ).name, '*.xml' );
  62.     % 在這個子資料夾下找字尾為xml的檔案
  63.     xmls = dir( subdirpath );   
  64.     % 遍歷每個xml
  65.     for j = 1 : length( xmls )
  66.         xmlpath = fullfile( maindir, subdir( i ).name, xmls( j ).name  );
  67.         %imgdata = imread( imagepath );   
  68.         % 下面進行你的讀取操作
  69.         %讀入xml檔案
  70.         xmldoc=xml_read(xmlpath); 
  71.         %讀取檔案有多少個框
  72.         L=length(xmldoc.object);
  73.         %更新總的框數
  74.         all_boxs_number = all_boxs_number+ L; 
  75.         %更新每類的框數
  76.         for k = 1 : length( L )
  77.             %第一次標註
  78.            switch xmldoc.object(k).name 
  79.                %懸垂線夾
  80.             case 'pre-twisted suspension clamp'
  81.                 pre_twisted_suspension_clamp_boxs_number = pre_twisted_suspension_clamp_boxs_number + 1;
  82.             case 'bag-type suspension clamp'
  83.                 bag_type_suspension_clamp_boxs_number = bag_type_suspension_clamp_boxs_number + 1;
  84.             case 'jumper suspension clamp'
  85.                 jumper_suspension_clamp_boxs_number = jumper_suspension_clamp_boxs_number + 1;
  86.                 %耐張線夾
  87.             case 'bolt-type strain clamp'
  88.                 bolt_type_strain_clamp_boxs_number = bolt_type_strain_clamp_boxs_number + 1;
  89.             case 'compression-type strain clamp'
  90.                 compression_type_strain_clamp_boxs_number = compression_type_strain_clamp_boxs_number + 1;
  91.             case 'wedge-type strain clamp'
  92.                 wedge_type_strain_clamp_boxs_number = wedge_type_strain_clamp_boxs_number + 1;
  93.                 %連線金具
  94.             case 'hanging board'
  95.                 hanging_board_boxs_number = hanging_board_boxs_number + 1;
  96.             case 'u-type hanging ring'
  97.                 u_type_hanging_ring_boxs_number = u_type_hanging_ring_boxs_number + 1;
  98.             case 'yoke plate'
  99.                 yoke_plate_boxs_number = yoke_plate_boxs_number + 1;
  100.                 %接續金具
  101.             case 'parallel groove clamp'
  102.                 parallel_groove_clamp_boxs_number = parallel_groove_clamp_boxs_number + 1;
  103.             case 'single slot wire clip'
  104.                 single_slot_wire_clip_boxs_number = single_slot_wire_clip_boxs_number + 1;
  105.                 %保護金具
  106.             case 'shockproof hammer'
  107.                 shockproof_hammer_boxs_number = shockproof_hammer_boxs_number + 1;
  108.             case 'spacer'
  109.                 spacer_boxs_number = spacer_boxs_number + 1;
  110.             case 'grading ring'
  111.                 grading_ring_boxs_number = grading_ring_boxs_number + 1;
  112.             case 'shielded ring'
  113.                 shielded_ring_boxs_number = shielded_ring_boxs_number + 1;
  114.             case 'weight'
  115.                 weight_boxs_number = weight_boxs_number + 1;
  116.                 %螺母
  117.             case 'nut loosening'
  118.                 nut_loosening_boxs_number = nut_loosening_boxs_number + 1;
  119.             case 'nut losing'
  120.                 nut_losing_boxs_number = nut_losing_boxs_number + 1;
  121.             case 'nut directly loosening'
  122.                 nut_directly_loosening_bolt_boxs_number = nut_directly_loosening_bolt_boxs_number + 1;
  123.             case 'nut indirectly loosening'    
  124.                 nut_indirectly_loosening_bolt_boxs_number = nut_indirectly_loosening_bolt_boxs_number + 1;
  125.                 %銷子
  126.             case 'visible pin losing'
  127.                 visible_pin_losing_boxs_number = visible_pin_losing_boxs_number + 1;
  128.             case 'invisible pin losing'      
  129.                 invisible_pin_losing_boxs_number = invisible_pin_losing_boxs_number + 1;
  130.             case 'pin closing'
  131.                 pin_closing_boxs_number = pin_closing_boxs_number + 1;
  132.             case 'pin loosening'
  133.                 pin_loosening_boxs_number = pin_loosening_boxs_number + 1;
  134.             case 'pin losing'
  135.                 pin_losing_boxs_number = pin_losing_boxs_number + 1;
  136.             case 'normal bolt'
  137.                 normal_bolt_boxs_number = normal_bolt_boxs_number + 1;
  138.                 %碗頭
  139.             case 'normal bowl head'
  140.                 normal_bowl_head_boxs_number = normal_bowl_head_boxs_number + 1;
  141.             case 'bowl head pin closing'
  142.                 bowl_head_pin_closing_boxs_number = bowl_head_pin_closing_boxs_number + 1;
  143.             case 'bowl head pin loosening'
  144.                 bowl_head_pin_loosening_boxs_number = bowl_head_pin_loosening_boxs_number + 1;
  145.             case 'bowl head pin losing'
  146.                 bowl_head_pin_losing_boxs_number = bowl_head_pin_losing_boxs_number + 1;
  147.            end
  148.         end
  149.     %   strrep 進行字串替換,區分大小寫   
  150.     %   strrep(str1,str2,str3)   
  151.     %      它把str1中所有的str2字串用str3來替換  
  152.     %newname = strrep(xmls( j ).name,'.xml','.txt')%%重新命名  
  153.    end   
  154. end  
  155. fprintf(fid,'%s %d\n','所有框數',all_boxs_number);
  156. %%懸垂線夾
  157. fprintf(fid,'%s %d\n','1.懸垂線夾:');
  158. fprintf(fid,'%s %d\n','1.1 pre-twisted suspension clamp 預絞式懸垂線夾',pre_twisted_suspension_clamp_boxs_number);
  159. fprintf(fid,'%s %d\n','1.2bag-type suspension clamp 提包式懸垂線夾',bag_type_suspension_clamp_boxs_number);
  160. %fprintf(fid,'%s %d\n','jumper suspension clamp',jumper_suspension_clamp_boxs_number);
  161. %%耐張線夾
  162. fprintf(fid,'%s %d\n','2.耐張線夾:');
  163. fprintf(fid,'%s %d\n','2.1 bolt-type strain clamp 螺栓型耐張線夾', bolt_type_strain_clamp_boxs_number);
  164. fprintf(fid,'%s %d\n','2.2 compression-type strain clamp 壓縮型耐張線夾',compression_type_strain_clamp_boxs_number);
  165. fprintf(fid,'%s %d\n','2.3 wedge-type strain clamp 鍥型耐張線夾',wedge_type_strain_clamp_boxs_number);
  166. %%連線金具
  167. fprintf(fid,'%s %d\n','3.連線金具:');
  168. fprintf(fid,'%s %d\n','3.1 hanging board 掛板',hanging_board_boxs_number);
  169. fprintf(fid,'%s %d\n','3.2 u-type hanging ring u型掛環',u_type_hanging_ring_boxs_number);
  170. fprintf(fid,'%s %d\n','3.3 yoke plate 聯板',yoke_plate_boxs_number);
  171. %%接續金具
  172. fprintf(fid,'%s %d\n','4.接續金具:');
  173. fprintf(fid,'%s %d\n','4.1 parallel groove clamp 並溝線夾',parallel_groove_clamp_boxs_number);
  174. fprintf(fid,'%s %d\n','4.2 single slot wire clip 單槽線夾',single_slot_wire_clip_boxs_number);
  175. %%防護金具
  176. fprintf(fid,'%s %d\n','5.防護金具:');
  177. fprintf(fid,'%s %d\n','5.1 shockproof hammer 防震錘',shockproof_hammer_boxs_number);
  178. fprintf(fid,'%s %d\n','5.2 spacer 間隔棒',spacer_boxs_number);
  179. fprintf(fid,'%s %d\n','5.3 grading ring 均壓環',grading_ring_boxs_number);
  180. fprintf(fid,'%s %d\n','5.4 shielded ring 遮蔽環',shielded_ring_boxs_number);
  181. fprintf(fid,'%s %d\n','5.5 weight 重錘',weight_boxs_number);
  182. %%正常螺栓
  183. fprintf(fid,'%s %d\n','normal bolt 正常螺栓',normal_bolt_boxs_number);
  184. %%螺栓-螺母
  185. fprintf(fid,'%s %d\n','5.螺母:');
  186. fprintf(fid,'%s %d\n','5.1 nut loosening 螺母鬆動',nut_loosening_boxs_number);
  187. fprintf(fid,'%s %d\n','5.2 nut losing 螺母缺失',nut_losing_boxs_number);
  188. fprintf(fid,'%s %d\n','5.3 nut directly loosening 螺母直接鬆動',nut_directly_loosening_bolt_boxs_number);
  189. fprintf(fid,'%s %d\n','5.4 nut indirectly loosening 螺母間接鬆動',nut_indirectly_loosening_bolt_boxs_number);
  190. %%螺栓-銷子
  191. fprintf(fid,'%s %d\n','6.銷子:');
  192. fprintf(fid,'%s %d\n','6.1 pin loosening 銷子鬆動',pin_loosening_boxs_number);
  193. fprintf(fid,'%s %d\n','6.2 pin losing 銷子脫落',pin_losing_boxs_number);
  194. fprintf(fid,'%s %d\n','6.3 pin closing 銷口閉合',pin_closing_boxs_number);
  195. fprintf(fid,'%s %d\n','6.4 visible pin losing 可見銷子脫落',visible_pin_losing_boxs_number);
  196. fprintf(fid,'%s %d\n','6.5 invisible pin losing 不可見銷子脫落',invisible_pin_losing_boxs_number);
  197. %%碗頭
  198. fprintf(fid,'%s %d\n','6.碗頭:');
  199. fprintf(fid,'%s %d\n','6.1 normal bowl head 正常碗頭',normal_bowl_head_boxs_number);
  200. fprintf(fid,'%s %d\n','6.2 bowl head pin closing 碗頭銷口閉合',bowl_head_pin_closing_boxs_number);
  201. fprintf(fid,'%s %d\n','6.3 bowl head pin loosening 碗頭銷子鬆動',bowl_head_pin_loosening_boxs_number);
  202. fprintf(fid,'%s %d\n','6.4 bowl head pin losing 碗頭銷子脫落',bowl_head_pin_losing_boxs_number);
  203. %fprintf(fid,'%s %d\n',);
  204. fclose(fid);
  205. %%每次增加新類別需要在三個地方新增:設定某一類初始值、switch中增加新類判斷case語句、print 該類統計資訊。