MatrixBerryCore
xmlformat.m
Go to the documentation of this file.
1 function resXmlString = xmlformat(SData,attSwitch,name,level,SMetaData)
2 import mxberry.xml.*;
3 import mxberry.core.throwerror;
4 %
5 NL_SYMBOL = sprintf('\n');
6 SPRINTF_SPEC_NUMERIC='%0.16g ';
7 %
8 %
9 if nargin<1
10  throwerror('wrongInput','SData is an obligatory input argument');
11 end
12 if nargin<2
13  attSwitch = 'on';
14 else
15  attSwitch=lower(attSwitch);
16 end
17 isForceAtt=strcmpi(attSwitch,'forceon');
18 isAtt=isForceAtt||strcmpi(attSwitch,'on');
19 %
20 if nargin<3 || isempty(name)
21  name = 'root';
22 end
23 %
24 if nargin<4 || isempty(level)
25  level = 0;
26 end
27 %
28 if nargin<5
29  SMetaData=struct();
30 end
31 %
32 resXmlString = '';
33 if level==0
34  paddingStr=char.empty(1,0);
35 else
36  paddingStr(1,level)=' ';
37  paddingStr(:)=sprintf('\t');
38 end
39 %
40 SAttributes.name = name;
41 SAttributes.type = getClass(SData);
42 %
43 if level==0
44  fieldNameList=fieldnames(SMetaData);
45  %
46  attribList=strcat({' '},fieldNameList,'=',...
47  cellfun(@(x)sprintf('"%s"',SMetaData.(x)),fieldNameList,...
48  'UniformOutput',false));
49  attributesStr=[attribList{:}];
50  %
51  if isAtt
52  attributesStr = [attributesStr,' type="',SAttributes.type,'" '];
53  if getIsNotRow(SData)
54  sizeVec=size(SData);
55  SAttributes.size = mynum2str(sizeVec);
56  attributesStr=[attributesStr,...
57  'size="',SAttributes.size,'"'];
58  end
59  end
60  resXmlString = [resXmlString,'<',name,attributesStr];
61 end
62 %
63 if isempty(SData)
64  resXmlString = [resXmlString,'/> ',NL_SYMBOL];
65  return
66 end
67 
68 nextLevel=level+1;
69 %
70 switch lower(SAttributes.type)
71 
72  case {'char','string'}
73  %
74  contentStr=charFuncSubstitute(SData(:).');
75  resXmlString = [resXmlString,'>',contentStr,'</',name,'>',...
76  NL_SYMBOL];
77  %
78  case 'struct'
79  %
80  resXmlString = [resXmlString,'>',NL_SYMBOL];
81  fieldNameList = fieldnames(SData);
82  nFields=numel(fieldNameList);
83  nElem=numel(SData);
84  %
85  for iElem = 1:nElem
86  for iField = 1:nFields
87  %
88  fieldName=fieldNameList{iField};
89  SChild.content = SData(iElem).(fieldName);
90  SChild.attributes = '';
91  %
92  if isAtt
93  SChild.att.idx = iElem;
94  SChild.att.type = getClass(SChild.content);
95  %
96  SChild.attributes = [' type="',SChild.att.type,'" '];
97  if nElem>1
98  SChild.attributes = [' idx="',...
99  sprintf('%d',iElem),'"',SChild.attributes];
100  end
101  if getIsNotRow(SChild.content)
102  sizeVec=size(SChild.content);
103  SChild.att.size = deblank(sprintf('%d ',sizeVec));
104  SChild.attributes=[SChild.attributes,...
105  'size="',SChild.att.size,'"'];
106  end
107  end
108  %
109  resXmlString = [resXmlString,paddingStr,'<',...
110  fieldName,SChild.attributes];
111  %
112  str =xmlformat(SChild.content,attSwitch,fieldName,...
113  nextLevel);
114  %
115  resXmlString = [resXmlString,str];
116  end
117  end
118  resXmlString = [resXmlString,paddingStr(1:end-1),'</',...
119  name,'>',NL_SYMBOL];
120  %
121  case 'cell'
122  resXmlString = [resXmlString,'>',NL_SYMBOL];
123  nElem=numel(SData);
124  for iElem=1:nElem
125  SChild.content = SData{iElem};
126  %
127  resXmlString = [resXmlString,paddingStr,'<item']; %#ok<*AGROW>
128  if isAtt
129  SChild.att.idx = iElem;
130  SChild.att.type = getClass(SChild.content);
131  SChild.attributes = [' type="',SChild.att.type,'" '];
132  %
133  if getIsNotRow(SChild.content)
134  SChild.att.size = mynum2str(size(SChild.content));
135  SChild.attributes=[SChild.attributes,'size="',...
136  SChild.att.size,'"'];
137  end
138  resXmlString = [resXmlString,SChild.attributes];
139  end
140  % write content
141  resXmlString = [resXmlString,xmlformat(SChild.content,...
142  attSwitch,'item',nextLevel)];
143  end
144  resXmlString = [resXmlString,paddingStr(1:end-1),...
145  '</',name,'>',NL_SYMBOL];
146  otherwise
147  try
148  contentStr = sprintf(SPRINTF_SPEC_NUMERIC,SData(:));
149  catch meObj
150  newObj=mxberry.core.throwerror('wrongInput:wrongType',...
151  'type %s is not supported',SAttributes.type);
152  newObj=addCause(newObj,meObj);
153  throw(newObj);
154  end
155  resXmlString = [resXmlString,'>',contentStr(1:end-1),...
156  '</',name,'>',NL_SYMBOL];
157 end
158  function className = getClass(inpVal)
159  if isnumeric(inpVal)
160  if ~isreal(inpVal)||issparse(inpVal)
161  mxberry.core.throwerror('wrongInput:wrongType',...
162  'complex or sparse values are not supported');
163  end
164  %
165  end
166  className=class(inpVal);
167  end
168  function isPositive=getIsNotRow(inpArray)
169  isPositive=isForceAtt||isempty(inpArray)||~isrow(inpArray);
170  end
171  function s=mynum2str(aVec)
172  s=sprintf('%d ',aVec);
173  s=s(1:end-1);
174  end
175 end
176 %
177 function content=charFuncSubstitute(content)
178 content=strrep(content,'&','&amp;');
179 content=strrep(content,'<','&lt;');
180 content=strrep(content,'>','&gt;');
181 content=strrep(content,'''','&apos;');
182 content=strrep(content,'"','&quot;');
183 end
function throwerror(in msgTag, in varargin)
THROWERROR works similarly to built-in ERROR function in case when there is no output arguments but s...
function mynum2str(in aVec)
function getIsNotRow(in inpArray)
function xmlformat(in SData, in attSwitch, in name, in level, in SMetaData)
XMLFORMAT formats the variable V into a name-based tag XML string xstr.
function getClass(in inpVal)
function charFuncSubstitute(in content)