Sunday, 15 November 2015

How to convert a matlab structure to xml file

Once a time I wanted to convert a matlab structure into an xml file. I know there are many ready solutions but I wanted one which fit exactly my needs. Let's say that we have a structure Student like this:

Student.Firstname = 'George';
Student.Surname = 'Hames';
Student.Age = 19;
Student.Semester = 'C';
Student.Course1.Grade = 8;
Student.Course2.Grade = 7;
Student.Course3.Grade = 9;
Student.Course4.Grade = 5;

and we want to convert it into this xml file:

<Student>
   <Firstname>George</Firstname>
   <Surname>Hames</Surname>
   <Age>19</Age>
   <Semester>C</Semester>
   <Course1>
      <Grade>8</Grade>
   </Course1>
   <Course2>
      <Grade>7</Grade>
   </Course2>
   <Course3>
      <Grade>9</Grade>
   </Course3>
   <Course4>
      <Grade>5</Grade>
   </Course4>
</Student>

My draft solution is this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function xml = struct2xml( s )

sfields = fieldnames(s);

xml = '';
for i=1:length(sfields)
    if isstruct(s.(sfields{i}))
            xml = [xml, strtrim(strcat('<', sfields{i}, '>')), char(10),  strtrim([struct2xml(s.(sfields{i})), strcat('</', sfields{i}, '>')]), char(10)]; 
    else
            fieldValue = s.(sfields{i});
            if (iscell(fieldValue))
                if (size(fieldValue,1)>1), fieldValue = fieldValue'; end;
                fieldValue = strjoin(fieldValue, '#');
            end
            if (isnumeric(fieldValue) && length(fieldValue)>1)
                fieldValueStr = '';
                for j=1:length(fieldValue)
                    fieldValueStr = strcat(fieldValueStr, num2str(fieldValue(j)), '#');
                end
                fieldValue = fieldValueStr(1:length(fieldValueStr)-1);
            end
            if (isnumeric(fieldValue) && length(fieldValue)==1)
                fieldValue = num2str(fieldValue);
            end
            xml = [xml, strcat('<', sfields{i}, '>', char(fieldValue), '</', sfields{i}, '>'), char(10)];
    end
end

end

First of all I have to say that it is not the optimum solution but it works for me. If a field takes multiple values, I use a delimiter (#) to represent them as a string. For example if struct1.field1 = [1 3 40 2] then in the xml we have <struct1><field1>1#3#40#2</field1></struct1>. In order to write the xml string to a file I use the following script:

1
2
3
4
5
6
7
function [] = struct2xmlfile( s, filename )
    xmlStr = struct2xml(s);
    xmlStr = strrep(xmlStr, '%', '%%');
    fid = fopen(filename, 'wt');
    fprintf(fid, xmlStr);
    fclose(fid);
end

No comments:

Post a Comment