savexml.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. function savexml(filename, varargin)
  2. %SAVEXML Save workspace variables to disk in XML.
  3. % SAVEXML FILENAME saves all workspace variables to the XML-file
  4. % named FILENAME.xml. The data may be retrieved with LOADXML. if
  5. % FILENAME has no extension, .xml is assumed.
  6. %
  7. % SAVE, by itself, creates the XML-file named 'matlab.xml'. It is
  8. % an error if 'matlab.xml' is not writable.
  9. %
  10. % SAVE FILENAME X saves only X.
  11. % SAVE FILENAME X Y Z saves X, Y, and Z. The wildcard '*' can be
  12. % used to save only those variables that match a pattern.
  13. %
  14. % SAVE ... -APPEND adds the variables to an existing file.
  15. %
  16. % Use the functional form of SAVE, such as SAVE(filename','var1','var2'),
  17. % when the filename or variable names are stored in strings.
  18. %
  19. % See also SAVE, MAT2XML, XMLTREE.
  20. % Copyright 2003 Guillaume Flandin.
  21. % $Revision: 6530 $ $Date: 2003/07/10 13:50 $
  22. % $Id: savexml.m 6530 2015-08-21 14:43:52Z guillaume $
  23. if nargin == 0
  24. filename = 'matlab.xml';
  25. fprintf('\nSaving to: %s\n\n',filename);
  26. else
  27. if ~ischar(filename)
  28. error('[SAVEXML] Argument must contain a string.');
  29. end
  30. [pathstr,name,ext] = fileparts(filename);
  31. if isempty(ext)
  32. filename = [filename '.xml'];
  33. end
  34. end
  35. if nargin <= 1, varargin = {'*'}; end
  36. if nargout > 0
  37. error('[SAVEXML] Too many output arguments.');
  38. end
  39. if strcmpi(varargin{end},'-append')
  40. if length(varargin) > 1
  41. varargin = varargin(1:end-1);
  42. else
  43. varargin = {'*'};
  44. end
  45. if exist(filename,'file')
  46. % TODO % No need to parse the whole tree ? detect duplicate variables ?
  47. t = xmltree(filename);
  48. else
  49. error(sprintf(...
  50. '[SAVEXML] Unable to write file %s: file does not exist.',filename));
  51. end
  52. else
  53. t = xmltree('<matfile/>');
  54. end
  55. for i=1:length(varargin)
  56. v = evalin('caller',['whos(''' varargin{i} ''')']);
  57. if isempty(v)
  58. error(['[SAVEXML] Variable ''' varargin{i} ''' not found.']);
  59. end
  60. for j=1:length(v)
  61. [t, uid] = add(t,root(t),'element',v(j).name);
  62. t = attributes(t,'add',uid,'type',v(j).class);
  63. t = attributes(t,'add',uid,'size',xml_num2str(v(j).size));
  64. t = xml_var2xml(t,evalin('caller',v(j).name),uid);
  65. end
  66. end
  67. save(t,filename);
  68. %=======================================================================
  69. function t = xml_var2xml(t,v,uid)
  70. switch class(v)
  71. case {'double','single','logical'}
  72. if ~issparse(v)
  73. t = add(t,uid,'chardata',xml_num2str(v));
  74. else % logical
  75. [i,j,s] = find(v);
  76. [t, uid2] = add(t,uid,'element','row');
  77. t = attributes(t,'add',uid2,'size',xml_num2str(size(i)));
  78. t = add(t,uid2,'chardata',xml_num2str(i));
  79. [t, uid2] = add(t,uid,'element','col');
  80. t = attributes(t,'add',uid2,'size',xml_num2str(size(j)));
  81. t = add(t,uid2,'chardata',xml_num2str(j));
  82. [t, uid2] = add(t,uid,'element','val');
  83. t = attributes(t,'add',uid2,'size',xml_num2str(size(s)));
  84. t = add(t,uid2,'chardata',xml_num2str(s));
  85. end
  86. case 'struct'
  87. names = fieldnames(v);
  88. for j=1:prod(size(v))
  89. for i=1:length(names)
  90. [t, uid2] = add(t,uid,'element',names{i});
  91. t = attributes(t,'add',uid2,'index',num2str(j));
  92. t = attributes(t,'add',uid2,'type',...
  93. class(getfield(v(j),names{i})));
  94. t = attributes(t,'add',uid2,'size', ...
  95. xml_num2str(size(getfield(v(j),names{i}))));
  96. t = xml_var2xml(t,getfield(v(j),names{i}),uid2);
  97. end
  98. end
  99. case 'cell'
  100. for i=1:prod(size(v))
  101. [t, uid2] = add(t,uid,'element','cell');
  102. % TODO % special handling of cellstr ?
  103. t = attributes(t,'add',uid2,'index',num2str(i));
  104. t = attributes(t,'add',uid2,'type',class(v{i}));
  105. t = attributes(t,'add',uid2,'size',xml_num2str(size(v{i})));
  106. t = xml_var2xml(t,v{i},uid2);
  107. end
  108. case 'char'
  109. % TODO % char values should be in CData
  110. if size(v,1) > 1
  111. t = add(t,uid,'chardata',v'); % row-wise order
  112. else
  113. t = add(t,uid,'chardata',v);
  114. end
  115. case {'int8','uint8','int16','uint16','int32','uint32'}
  116. [t, uid] = add(t,uid,'element',class(v));
  117. % TODO % Handle integer formats (cannot use sprintf or num2str)
  118. otherwise
  119. if ismember('serialize',methods(class(v)))
  120. % TODO % is CData necessary for class output ?
  121. t = add(t,uid,'cdata',serialize(v));
  122. else
  123. warning(sprintf(...
  124. '[SAVEXML] Cannot convert from %s to XML.',class(v)));
  125. end
  126. end
  127. %=======================================================================
  128. function s = xml_num2str(n)
  129. % TODO % use format ?
  130. if isempty(n)
  131. s = '[]';
  132. else
  133. s = ['[' sprintf('%g ',n(1:end-1))];
  134. s = [s num2str(n(end)) ']'];
  135. end