Code covered by the BSD License  

Highlights from
XML data import

image thumbnail
from XML data import by Matt G
Returns data stored in an xml file to a variable or multiple variables.

xmlData(xmlFile,xml2matTrans,varargin)
function [ varargout ] = xmlData(xmlFile,xml2matTrans,varargin)
%XMLDATA reads a xml file (transformed if required) and returns the
%specified elements
%   [v1]=xmlData(xmlFile,xmlTransform,'var1') extracts
%   XML element "var1" text from a XML file "xmlFile" transformed by a 
%   XLST transform "xml2matTrans".  The evaluated text content of "var1" 
%   is output to variable v1.  "var1" is an element (after being
%   transformed): <var1>[1,0,;0,1,;]</var1>  the above function is
%   equivalent to v1=eval('[[1;0;] [0;1;] ])
%   xmlTransform may be [] if xml file does not need to be transformed
%
%   [v1,...,vn]=xmlData(xmlFile,xmlTransform,'var1',...,'varn') extracts
%   XML element "var1" thru "varn" evaluates the text content and 
%   outputs to variables v1 thru vn
%
%   [v]=xmlData(xmlFile,xmlTransform,'var1',...,'varn') extracts
%   XML element "var1" thru "varn" and stores each evaluated text content
%   in a structure field of v
%   	fieldnames(v)
%             ans = 
%                 'var1'
%                 ...
%                 'varn'
%
%   [v]=xmlData(xmlFile,xmlTransform) extracts all transformed XML 
%   elements under the root node and stores the evaluated text content 
%   	fieldnames(a)
%             ans = 
%                 'var1'
%                 ...
%                 'varn'
%   [v]=xmlData(xmlFile) extracts all XML elements under the
%   root node and stores the evaluated text content 
%   	fieldnames(v)
%             ans = 
%                 'var1'
%                 ...
%                 'varn'
%
%xml transformed into:
% <?xml version="1.0" encoding="utf-8"?>
% <constants>
%    <piSlice>[[3.14;] ]</piSlice>
%    <deg2rad>[[0.017453292519943;] ]</deg2rad>
%    <primes3x2>[[2;3;5;] [7;11;13;] ]</primes3x2>
%    <testMat2>[[{'Hello'};] [{'world'}] ]</testMat2>
% </constants>
%
%the transformed xml file or (input xml file itself if no transform
%specified) must have a root element named "constants".  The child elements
%can be any valid xml tag name.  The inner text of the child elements must 
%be a valid expression to assign to the respective variable.  
%ie var1=eval('[[3.14;] ]')
%
%Example 1: Get specific child elements of "constants"
%   [p1e p]=xmlData('sample.xml','const2mat.xsl','piSlice','primes3x2')
% p1e =
%     3.1400
% p =
% 
%      2     7
%      3    11
%      5    13
%Example 2 return all child elements of "constants" to a structure
% [a]=xmlData('sample.xml','const2mat.xsl')
% a = 
%       piSlice: 3.1400
%       deg2rad: 0.0175
%     primes3x2: [3x2 double]
%      testMat2: {'Hello'  'world'}
%
%See also xmlread xslt java

%% check inputs and outputs
outputStructure=false; %use this as a flag 
checkInputs(nargin,nargout);
%this is broken into a nested fuction to drive down complexity
%mlint('xmlData','-cyc') %check complexity
function checkInputs(nin,nout) 
    %nin=nargin of calling function
    %nout=nargout of calling function
    if nin==1
     xml2matTrans=[];
    end

    if nin>2
        %check 3rd input
        if ~iscellstr(varargin)
            error('xmlFile:IO','Inputs 3 to n must be of type char')
        end

        if nout<=1 && length(varargin)~=1
            %1 output ok also, that can be a structure 
            outputStructure=true; 
        elseif nout~=length(varargin)
            error('xmlFile:IO',['Number of outputs must equal the '...
                'number of constants to retrieve, '...
                'one output may also be used for a structure.'])
        end
    end
    
    %if 2nd arg is [] or only 1 arg is specified, use input xml file only
    if ~isempty(xml2matTrans)
        %transform data
        s=xslt(xmlFile,xml2matTrans,'-tostring');
        reader = java.io.StringReader(s);
        xmlFile = org.xml.sax.InputSource(reader);
    end
end %checkInputs


%% create the xml document to use with the DOM
xDoc=xmlread(xmlFile);

%% case of nargin==2get all the element names
if nargin==2
    %output needs to be checked again; varargout can be length 0, 1 or the
    %number of contstants in the file
    if nargout>1 && (nargout~=length(varargin))
        error('xmlFile:IO',['When not specifiying a third input the '...
            'number of outputs must equal the number of elements '...
            'retrieved or 1 (for structure)'])
    end
    varargin=getContsList;
    if length(varargin)>1
         outputStructure=true;
    end
end

%% get values
output=cell(size(varargin));
for p=1:length(varargin)
    elm=xDoc.getElementsByTagName(varargin{p});
    if elm.getLength==0
        error('xmlFile:IO','"%s is not a valid tag',varargin{p})
    end
    output{p}=eval(elm.item(0).getTextContent);
end %p loop

if outputStructure
    varargout = {cell2struct(output, varargin, 2)};
else
    varargout =output;
end


%% nested function to extract all the child element of "constants"
    function listConstants=getContsList
        %gets a cell array of the names of the constants
        allListItems = xDoc.getElementsByTagName('constants');
        for m=allListItems.item(0).getChildNodes.getLength-1:-1:0
            %remmove non element elements (whitespace)
            if allListItems.item(0).getChildNodes.item(m).getNodeType~=1
                nonElm=allListItems.item(0).getChildNodes.item(m);
                allListItems.item(0).removeChild(nonElm);
            end            
        end %m loop
        %now get all the names
        listConstants=cell(1,...
            allListItems.item(0).getChildNodes.getLength);%preallocate
        for n=0:allListItems.item(0).getChildNodes.getLength-1
            listConstants(1,n+1)=...
                allListItems.item(0).getChildNodes.item(n).getNodeName;
        end %n loop
    end %getContsList

end % xmlData

Contact us at files@mathworks.com