1 | function varargout = save(tree, filename)
|
---|
2 | % XMLTREE/SAVE Save an XML tree in an XML file
|
---|
3 | % FORMAT varargout = save(tree,filename)
|
---|
4 | %
|
---|
5 | % tree - XMLTree
|
---|
6 | % filename - XML output filename
|
---|
7 | % varargout - XML string
|
---|
8 | %__________________________________________________________________________
|
---|
9 | %
|
---|
10 | % Convert an XML tree into a well-formed XML string and write it into
|
---|
11 | % a file or return it as a string if no filename is provided.
|
---|
12 | %__________________________________________________________________________
|
---|
13 | % Copyright (C) 2002-2011 http://www.artefact.tk/
|
---|
14 |
|
---|
15 | % Guillaume Flandin
|
---|
16 | % $Id: save.m 4460 2011-09-05 14:52:16Z guillaume $
|
---|
17 |
|
---|
18 |
|
---|
19 | %error(nargchk(1,2,nargin));
|
---|
20 |
|
---|
21 | prolog = '<?xml version="1.0" ?>\n';
|
---|
22 |
|
---|
23 | %- Return the XML tree as a string
|
---|
24 | if nargin == 1
|
---|
25 | varargout{1} = [sprintf(prolog) ...
|
---|
26 | print_subtree(tree,'',root(tree))];
|
---|
27 | %- Output specified
|
---|
28 | else
|
---|
29 | %- Filename provided
|
---|
30 | if ischar(filename)
|
---|
31 | [fid, msg] = fopen(filename,'w');
|
---|
32 | if fid==-1, error(msg); end
|
---|
33 | if isempty(tree.filename), tree.filename = filename; end
|
---|
34 | %- File identifier provided
|
---|
35 | elseif isnumeric(filename) && numel(filename) == 1
|
---|
36 | fid = filename;
|
---|
37 | prolog = ''; %- With this option, do not write any prolog
|
---|
38 | else
|
---|
39 | error('[XMLTree] Invalid argument.');
|
---|
40 | end
|
---|
41 | fprintf(fid,prolog);
|
---|
42 | save_subtree(tree,fid,root(tree));
|
---|
43 | if ischar(filename), fclose(fid); end
|
---|
44 | if nargout == 1
|
---|
45 | varargout{1} = print_subtree(tree,'',root(tree));
|
---|
46 | end
|
---|
47 | end
|
---|
48 |
|
---|
49 | %==========================================================================
|
---|
50 | function xmlstr = print_subtree(tree,xmlstr,uid,order)
|
---|
51 | if nargin < 4, order = 0; end
|
---|
52 | xmlstr = [xmlstr blanks(3*order)];
|
---|
53 | switch tree.tree{uid}.type
|
---|
54 | case 'element'
|
---|
55 | xmlstr = sprintf('%s<%s',xmlstr,tree.tree{uid}.name);
|
---|
56 | for i=1:length(tree.tree{uid}.attributes)
|
---|
57 | xmlstr = sprintf('%s %s="%s"', xmlstr, ...
|
---|
58 | tree.tree{uid}.attributes{i}.key,...
|
---|
59 | tree.tree{uid}.attributes{i}.val);
|
---|
60 | end
|
---|
61 | if isempty(tree.tree{uid}.contents)
|
---|
62 | xmlstr = sprintf('%s/>\n',xmlstr);
|
---|
63 | else
|
---|
64 | xmlstr = sprintf('%s>\n',xmlstr);
|
---|
65 | for i=1:length(tree.tree{uid}.contents)
|
---|
66 | xmlstr = print_subtree(tree,xmlstr, ...
|
---|
67 | tree.tree{uid}.contents(i),order+1);
|
---|
68 | end
|
---|
69 | xmlstr = [xmlstr blanks(3*order)];
|
---|
70 | xmlstr = sprintf('%s</%s>\n',xmlstr,...
|
---|
71 | tree.tree{uid}.name);
|
---|
72 | end
|
---|
73 | case 'chardata'
|
---|
74 | xmlstr = sprintf('%s%s\n',xmlstr, ...
|
---|
75 | entity(tree.tree{uid}.value));
|
---|
76 | case 'cdata'
|
---|
77 | xmlstr = sprintf('%s<![CDATA[%s]]>\n',xmlstr, ...
|
---|
78 | tree.tree{uid}.value);
|
---|
79 | case 'pi'
|
---|
80 | xmlstr = sprintf('%s<?%s %s?>\n',xmlstr, ...
|
---|
81 | tree.tree{uid}.target, tree.tree{uid}.value);
|
---|
82 | case 'comment'
|
---|
83 | xmlstr = sprintf('%s<!-- %s -->\n',xmlstr,...
|
---|
84 | tree.tree{uid}.value);
|
---|
85 | otherwise
|
---|
86 | warning(sprintf('Type %s unknown: not saved', ...
|
---|
87 | tree.tree{uid}.type));
|
---|
88 | end
|
---|
89 |
|
---|
90 | %==========================================================================
|
---|
91 | function save_subtree(tree,fid,uid,order)
|
---|
92 | if nargin < 4, order = 0; end
|
---|
93 | fprintf(fid,blanks(3*order));
|
---|
94 | switch tree.tree{uid}.type
|
---|
95 | case 'element'
|
---|
96 | fprintf(fid,'<%s',tree.tree{uid}.name);
|
---|
97 | for i=1:length(tree.tree{uid}.attributes)
|
---|
98 | fprintf(fid,' %s="%s"',...
|
---|
99 | tree.tree{uid}.attributes{i}.key, ...
|
---|
100 | tree.tree{uid}.attributes{i}.val);
|
---|
101 | end
|
---|
102 | if isempty(tree.tree{uid}.contents)
|
---|
103 | fprintf(fid,'/>\n');
|
---|
104 | else
|
---|
105 | fprintf(fid,'>\n');
|
---|
106 | for i=1:length(tree.tree{uid}.contents)
|
---|
107 | save_subtree(tree,fid,...
|
---|
108 | tree.tree{uid}.contents(i),order+1)
|
---|
109 | end
|
---|
110 | fprintf(fid,blanks(3*order));
|
---|
111 | fprintf(fid,'</%s>\n',tree.tree{uid}.name);
|
---|
112 | end
|
---|
113 | case 'chardata'
|
---|
114 | fprintf(fid,'%s\n',entity(tree.tree{uid}.value));
|
---|
115 | case 'cdata'
|
---|
116 | fprintf(fid,'<![CDATA[%s]]>\n',tree.tree{uid}.value);
|
---|
117 | case 'pi'
|
---|
118 | fprintf(fid,'<?%s %s?>\n',tree.tree{uid}.target, ...
|
---|
119 | tree.tree{uid}.value);
|
---|
120 | case 'comment'
|
---|
121 | fprintf(fid,'<!-- %s -->\n',tree.tree{uid}.value);
|
---|
122 | otherwise
|
---|
123 | warning(sprintf('[XMLTree] Type %s unknown: not saved', ...
|
---|
124 | tree.tree{uid}.type));
|
---|
125 | end
|
---|
126 |
|
---|
127 |
|
---|
128 | %==========================================================================
|
---|
129 | function str = entity(str)
|
---|
130 | % This has the side effect of strtrim'ming the char array.
|
---|
131 | str = char(strrep(cellstr(str), '&', '&' ));
|
---|
132 | str = char(strrep(cellstr(str), '<', '<' ));
|
---|
133 | str = char(strrep(cellstr(str), '>', '>' ));
|
---|
134 | str = char(strrep(cellstr(str), '"', '"'));
|
---|
135 | str = char(strrep(cellstr(str), '''', '''));
|
---|