function [v, tree] = xmlparse(xml)
%
% Translate an xml string into a matlab struct
%
% xml = '1344'
% xml = '1235614'
%
% [v, tree] = xmlparse(xml)
%
% This function replaces xml2struct.m to add more flexibility.
% Written by Antonio Torralba, June 2013
%keyboard
% xml 2 tree
tree = xml2tree(xml);
% tree 2 struct
v = tree2struct(tree, 0);
function v = tree2struct(tree, node)
v = [];
children = find(tree.parent==node);
if isempty(children)
return
end
tag = tree.tagname(children);
values = tree.value(children);
for n = 1:length(tag)
tagn = tag{n};
valn = values{n};
m=1;
if isfield(v, tagn) && n>1
m = 1+length(v.(tagn));
end
if ~isempty(valn)
if m==1
v.(tagn) = valn;
else
v.(tagn){m} = valn;
end
else
tmp = tree2struct(tree, children(n));
if ~isempty(tmp)
if m==1
v.(tagn) = tmp;
else
f = fieldnames(tmp);
ff = ~isfield(v.(tagn), f);
for mm = 1:length(f)
fm = f{mm};
if ff(mm) %~isfield(v.(tagn),f{mm})
v.(tagn)(1).(fm) = [];
end
v.(tagn)(m).(fm) = tmp.(fm);
end
end
end
end
end
function tree = xml2tree(xml)
% First replace entries by >
xml = strrep(xml, '/>', '>>');
xml = strrep(xml, '@', '_');
xml = strrep(xml, '#', '_');
xml = regexprep(xml, '>(\s*)<', '><'); % remove spaces between fields.
% split XML
pxml = strrep(xml, '', '$#'); % #=-
pxml = strrep(pxml, '<', '$@'); % @=+
pxml = strrep(pxml, '>', '$');
pxml = strrep(pxml, '$$', '$');
elements = regexp(pxml, '[$]', 'split');
elements = elements(~cellfun('isempty',elements));
N = sum(pxml=='@');
tree.parent = zeros(N,1);
tree.tagname = cell(N,1);
tree.value = cell(N,1);
% Loop and get tags. An open tag goes up in the struct level, and closing
% tag goes down.
currentnode = 0;
n = 0;
%keyboard
for e = elements
ee = e{1};
e1 = ee(1);
if e1=='@'
n = n+1;
tree.parent(n) = currentnode;
tree.tagname{n} = ee(2:end);
currentnode = n;
elseif e1=='#'
currentnode = tree.parent(currentnode);
else
tree.value{n} = strtrim(ee);
end
end