source: trunk/src/xml2struct.m @ 685

Last change on this file since 685 was 685, checked in by sommeria, 11 years ago

error message improved for reading xml files

File size: 3.3 KB
RevLine 
[356]1% 'xml2struct': read an xml file as a Matlab structure, converts numeric character strings into numbers
2%-----------------------------------------------------------------------
3% function s=xml2struct(filename)
4%
5% OUTPUT:
6% s= Matlab structure corresponding to the input xml file
7%
8% INPUT:
9% filename: name of the xml file
[560]10% varargin: optional list of strings to restrict the reading to a selection of subtrees, for instance 'GeometryCalib' (save time)
[356]11
[685]12function [s,Heading,errormsg]=xml2struct(filename,varargin)
13s=[];
14Heading='';
15errormsg='';
16try
[320]17t=xmltree(filename);
[685]18catch ME
19    errormsg=ME.message;
20    if regexp(ME.message,'xml_findstr')
21        errormsg=[errormsg ': xmltree not correctly installed, download from www.artefact.tk/software/matlab/xml'];
22    end
23    return
24end
[565]25iline=0;
[685]26
[565]27while isempty(Heading)
28    iline=iline+1;
29    if strcmp(get(t,iline,'type'),'element')
30        Heading=get(t,iline,'name');
31    end
32end
[560]33if nargin>1
34    for isub=1:nargin-1
35        uid_sub=find(t,['/' Heading '/' varargin{isub}]);
[565]36        if isempty(uid_sub)
37            s.(varargin{isub})=[];
38        else
[560]39        tsub=branch(t,uid_sub);
40        ss=convert(tsub);
41        s.(varargin{isub})=convert_string(ss);
[565]42        end
[560]43    end
44else
45    ss=convert(t);
46    s=convert_string(ss);
47end
[320]48
49
[450]50function out=convert_string(ss)
51info=whos('ss');
[320]52switch info.class
53    case 'struct'
[471]54        out=[];%default
[450]55        names = fieldnames(ss);
[320]56        for k=1:length(names)
[450]57            out.(names{k})=convert_string(ss.(names{k}));
[320]58        end
[663]59    case 'char'
60        out=ss; %reproduce the input string
[675]61        % try to convert to number if the char does not correspond to a function (otherwise str2num calls this function as it uses 'eval')
62        if ~isempty(regexp(ss,'^(-*\d+\.*\d*\ *)+$')) || ~isempty(regexp(ss,'\d+e(-|+)\d+')) % if the string corresponds to a set of numbers (with possible sign and decimal, or scientific notation) separated by blanks
[663]63            out=str2num(ss);
[675]64        else
65            sep_ind=regexp(ss,'\s&\s');% check for separator ' & ' which indicates column separation in tables
66            if ~isempty(sep_ind)
67                sep_ind=[-2 sep_ind length(ss)+1];
68                for icolumn=1:length(sep_ind)-1
69                    out{1,icolumn}=ss(sep_ind(icolumn)+3:sep_ind(icolumn+1)-1);
[450]70                end
[675]71            else
72                out=ss; %reproduce the input string
[450]73            end
[320]74        end
[379]75    case 'cell'
[471]76        out=[];%default
[477]77        check_numeric=zeros(size(ss));
78        for ilist=1:numel(ss)
[663]79            if ~strcmp(ss{ilist},'image') && ~isempty(str2num(ss{ilist}))
[477]80                out{ilist,1}=str2num(ss{ilist});
81                check_numeric(ilist)=1;
82            else
[472]83                sep_ind=regexp(ss{ilist},'\s&\s');% check for separator ' & ' which indicates column separation in tables
84                if ~isempty(sep_ind)
85                    sep_ind=[-2 sep_ind length(ss{ilist})+1];
86                    for icolumn=1:length(sep_ind)-1
87                        out{ilist,icolumn}=ss{ilist}(sep_ind(icolumn)+3:sep_ind(icolumn+1)-1);
88                    end
89                else
90                    out{ilist,1}=ss{ilist}; %reproduce the input string
91                end
[453]92            end
[379]93        end
[477]94        if isequal(check_numeric,ones(size(ss)))
95            out=cell2mat(out);
96        end
[320]97    otherwise
[450]98        out=ss;
[320]99end
100
101   
Note: See TracBrowser for help on using the repository browser.