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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Saving document</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="modify.html" title="Modifying document data">
<link rel="next" href="xpath.html" title="XPath">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> · <a href="loading.html">Loading</a> · <a href="access.html">Accessing</a> · <a href="modify.html">Modifying</a> · <b>Saving</b> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="modify.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="xpath.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.saving"></a><a class="link" href="saving.html" title="Saving document"> Saving document</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="saving.html#manual.saving.file"> Saving document to a file</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.stream"> Saving document to C++ IOstreams</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.writer"> Saving document via writer interface</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.subtree"> Saving a single subtree</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.options"> Output options</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.encoding"> Encodings</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.declaration"> Customizing document declaration</a></span></dt>
</dl></div>
<p>
Often after creating a new document or loading the existing one and processing
it, it is necessary to save the result back to file. Also it is occasionally
useful to output the whole document or a subtree to some stream; use cases
include debug printing, serialization via network or other text-oriented medium,
etc. pugixml provides several functions to output any subtree of the document
to a file, stream or another generic transport interface; these functions allow
to customize the output format (see <a class="xref" href="saving.html#manual.saving.options" title="Output options"> Output options</a>), and also perform
necessary encoding conversions (see <a class="xref" href="saving.html#manual.saving.encoding" title="Encodings"> Encodings</a>). This section documents
the relevant functionality.
</p>
<p>
Before writing to the destination the node/attribute data is properly formatted
according to the node type; all special XML symbols, such as < and &,
are properly escaped (unless <a class="link" href="saving.html#format_no_escapes">format_no_escapes</a>
flag is set). In order to guard against forgotten node/attribute names, empty
node/attribute names are printed as <code class="computeroutput"><span class="string">":anonymous"</span></code>.
For well-formed output, make sure all node and attribute names are set to meaningful
values.
</p>
<p>
CDATA sections with values that contain <code class="computeroutput"><span class="string">"]]>"</span></code>
are split into several sections as follows: section with value <code class="computeroutput"><span class="string">"pre]]>post"</span></code> is written as <code class="computeroutput"><span class="special"><![</span><span class="identifier">CDATA</span><span class="special">[</span><span class="identifier">pre</span><span class="special">]]]]><![</span><span class="identifier">CDATA</span><span class="special">[></span><span class="identifier">post</span><span class="special">]]></span></code>.
While this alters the structure of the document (if you load the document after
saving it, there will be two CDATA sections instead of one), this is the only
way to escape CDATA contents.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.file"></a><a class="link" href="saving.html#manual.saving.file" title="Saving document to a file"> Saving document to a file</a>
</h3></div></div></div>
<a name="xml_document::save_file"></a><a name="xml_document::save_file_wide"></a><p>
If you want to save the whole document to a file, you can use one of the
following functions:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save_file</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">path</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save_file</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">path</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
These functions accept file path as its first argument, and also three optional
arguments, which specify indentation and other output options (see <a class="xref" href="saving.html#manual.saving.options" title="Output options"> Output options</a>)
and output data encoding (see <a class="xref" href="saving.html#manual.saving.encoding" title="Encodings"> Encodings</a>). The path has the target
operating system format, so it can be a relative or absolute one, it should
have the delimiters of the target system, it should have the exact case if
the target file system is case-sensitive, etc.
</p>
<p>
File path is passed to the system file opening function as is in case of
the first function (which accepts <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">char</span><span class="special">*</span> <span class="identifier">path</span></code>); the second function either uses
a special file opening function if it is provided by the runtime library
or converts the path to UTF-8 and uses the system file opening function.
</p>
<a name="xml_writer_file"></a><p>
<code class="computeroutput"><span class="identifier">save_file</span></code> opens the target
file for writing, outputs the requested header (by default a document declaration
is output, unless the document already has one), and then saves the document
contents. If the file could not be opened, the function returns <code class="computeroutput"><span class="keyword">false</span></code>. Calling <code class="computeroutput"><span class="identifier">save_file</span></code>
is equivalent to creating an <code class="computeroutput"><span class="identifier">xml_writer_file</span></code>
object with <code class="computeroutput"><span class="identifier">FILE</span><span class="special">*</span></code>
handle as the only constructor argument and then calling <code class="computeroutput"><span class="identifier">save</span></code>;
see <a class="xref" href="saving.html#manual.saving.writer" title="Saving document via writer interface"> Saving document via writer interface</a> for writer interface details.
</p>
<p>
This is a simple example of saving XML document to file (<a href="../samples/save_file.cpp" target="_top">samples/save_file.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// save document to file
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Saving result: "</span> <span class="special"><<</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">save_file</span><span class="special">(</span><span class="string">"save_file_output.xml"</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.stream"></a><a class="link" href="saving.html#manual.saving.stream" title="Saving document to C++ IOstreams"> Saving document to C++ IOstreams</a>
</h3></div></div></div>
<a name="xml_document::save_stream"></a><p>
To enhance interoperability pugixml provides functions for saving document
to any object which implements C++ <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span></code>
interface. This allows you to save documents to any standard C++ stream (i.e.
file stream) or any third-party compliant implementation (i.e. Boost Iostreams).
Most notably, this allows for easy debug output, since you can use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code>
stream as saving target. There are two functions, one works with narrow character
streams, another handles wide character ones:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="identifier">stream</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">wostream</span><span class="special">&</span> <span class="identifier">stream</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">save</span></code> with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span></code>
argument saves the document to the stream in the same way as <code class="computeroutput"><span class="identifier">save_file</span></code> (i.e. with requested header and
with encoding conversions). On the other hand, <code class="computeroutput"><span class="identifier">save</span></code>
with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstream</span></code> argument saves the document to
the wide stream with <a class="link" href="loading.html#encoding_wchar">encoding_wchar</a>
encoding. Because of this, using <code class="computeroutput"><span class="identifier">save</span></code>
with wide character streams requires careful (usually platform-specific)
stream setup (i.e. using the <code class="computeroutput"><span class="identifier">imbue</span></code>
function). Generally use of wide streams is discouraged, however it provides
you with the ability to save documents to non-Unicode encodings, i.e. you
can save Shift-JIS encoded data if you set the correct locale.
</p>
<a name="xml_writer_stream"></a><p>
Calling <code class="computeroutput"><span class="identifier">save</span></code> with stream
target is equivalent to creating an <code class="computeroutput"><span class="identifier">xml_writer_stream</span></code>
object with stream as the only constructor argument and then calling <code class="computeroutput"><span class="identifier">save</span></code>; see <a class="xref" href="saving.html#manual.saving.writer" title="Saving document via writer interface"> Saving document via writer interface</a> for writer
interface details.
</p>
<p>
This is a simple example of saving XML document to standard output (<a href="../samples/save_stream.cpp" target="_top">samples/save_stream.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// save document to standard output
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Document:\n"</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.writer"></a><a class="link" href="saving.html#manual.saving.writer" title="Saving document via writer interface"> Saving document via writer interface</a>
</h3></div></div></div>
<a name="xml_document::save"></a><a name="xml_writer"></a><a name="xml_writer::write"></a><p>
All of the above saving functions are implemented in terms of writer interface.
This is a simple interface with a single function, which is called several
times during output process with chunks of document data as input:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">xml_writer</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">write</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">void</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">xml_writer</span><span class="special">&</span> <span class="identifier">writer</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
In order to output the document via some custom transport, for example sockets,
you should create an object which implements <code class="computeroutput"><span class="identifier">xml_writer</span></code>
interface and pass it to <code class="computeroutput"><span class="identifier">save</span></code>
function. <code class="computeroutput"><span class="identifier">xml_writer</span><span class="special">::</span><span class="identifier">write</span></code> function is called with a buffer
as an input, where <code class="computeroutput"><span class="identifier">data</span></code> points
to buffer start, and <code class="computeroutput"><span class="identifier">size</span></code>
is equal to the buffer size in bytes. <code class="computeroutput"><span class="identifier">write</span></code>
implementation must write the buffer to the transport; it can not save the
passed buffer pointer, as the buffer contents will change after <code class="computeroutput"><span class="identifier">write</span></code> returns. The buffer contains the
chunk of document data in the desired encoding.
</p>
<p>
<code class="computeroutput"><span class="identifier">write</span></code> function is called
with relatively large blocks (size is usually several kilobytes, except for
the last block that may be small), so there is often no need for additional
buffering in the implementation.
</p>
<p>
This is a simple example of custom writer for saving document data to STL
string (<a href="../samples/save_custom_writer.cpp" target="_top">samples/save_custom_writer.cpp</a>);
read the sample code for more complex examples:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">xml_string_writer</span><span class="special">:</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_writer</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span><span class="special">;</span>
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">write</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">result</span><span class="special">.</span><span class="identifier">append</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*>(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">size</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.subtree"></a><a class="link" href="saving.html#manual.saving.subtree" title="Saving a single subtree"> Saving a single subtree</a>
</h3></div></div></div>
<a name="xml_node::print"></a><a name="xml_node::print_stream"></a><p>
While the previously described functions save the whole document to the destination,
it is easy to save a single subtree. The following functions are provided:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="identifier">os</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">depth</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">wostream</span><span class="special">&</span> <span class="identifier">os</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">depth</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">xml_writer</span><span class="special">&</span> <span class="identifier">writer</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">depth</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
These functions have the same arguments with the same meaning as the corresponding
<code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span></code> functions, and allow you to save the
subtree to either a C++ IOstream or to any object that implements <code class="computeroutput"><span class="identifier">xml_writer</span></code> interface.
</p>
<p>
Saving a subtree differs from saving the whole document: the process behaves
as if <a class="link" href="saving.html#format_write_bom">format_write_bom</a> is off, and
<a class="link" href="saving.html#format_no_declaration">format_no_declaration</a> is on,
even if actual values of the flags are different. This means that BOM is
not written to the destination, and document declaration is only written
if it is the node itself or is one of node's children. Note that this also
holds if you're saving a document; this example (<a href="../samples/save_subtree.cpp" target="_top">samples/save_subtree.cpp</a>)
illustrates the difference:
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// get a test document
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="string">"<foo bar='baz'><call>hey</call></foo>"</span><span class="special">);</span>
<span class="comment">// print document to standard output (prints <?xml version="1.0"?><foo bar="baz"><call>hey</call></foo>)
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">""</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// print document to standard output as a regular node (prints <foo bar="baz"><call>hey</call></foo>)
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">""</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// print a subtree to standard output (prints <call>hey</call>)
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"foo"</span><span class="special">).</span><span class="identifier">child</span><span class="special">(</span><span class="string">"call"</span><span class="special">).</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">""</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.options"></a><a class="link" href="saving.html#manual.saving.options" title="Output options"> Output options</a>
</h3></div></div></div>
<p>
All saving functions accept the optional parameter <code class="computeroutput"><span class="identifier">flags</span></code>.
This is a bitmask that customizes the output format; you can select the way
the document nodes are printed and select the needed additional information
that is output before the document contents.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
You should use the usual bitwise arithmetics to manipulate the bitmask:
to enable a flag, use <code class="computeroutput"><span class="identifier">mask</span> <span class="special">|</span> <span class="identifier">flag</span></code>;
to disable a flag, use <code class="computeroutput"><span class="identifier">mask</span> <span class="special">&</span> <span class="special">~</span><span class="identifier">flag</span></code>.
</p></td></tr>
</table></div>
<p>
These flags control the resulting tree contents:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a name="format_indent"></a><code class="literal">format_indent</code> determines if all nodes
should be indented with the indentation string (this is an additional
parameter for all saving functions, and is <code class="computeroutput"><span class="string">"\t"</span></code>
by default). If this flag is on, before every node the indentation string
is output several times, where the amount of indentation depends on the
node's depth relative to the output subtree. This flag has no effect
if <a class="link" href="saving.html#format_raw">format_raw</a> is enabled. This flag
is <span class="bold"><strong>on</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="format_raw"></a><code class="literal">format_raw</code> switches between formatted and
raw output. If this flag is on, the nodes are not indented in any way,
and also no newlines that are not part of document text are printed.
Raw mode can be used for serialization where the result is not intended
to be read by humans; also it can be useful if the document was parsed
with <a class="link" href="loading.html#parse_ws_pcdata">parse_ws_pcdata</a> flag, to
preserve the original document formatting as much as possible. This flag
is <span class="bold"><strong>off</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="format_no_escapes"></a><code class="literal">format_no_escapes</code> disables output
escaping for attribute values and PCDATA contents. If this flag is off,
special symbols (', &, <, >) and all non-printable characters
(those with codepoint values less than 32) are converted to XML escape
sequences (i.e. &amp;) during output. If this flag is on, no text
processing is performed; therefore, output XML can be malformed if output
contents contains invalid symbols (i.e. having a stray < in the PCDATA
will make the output malformed). This flag is <span class="bold"><strong>off</strong></span>
by default.
</li>
</ul></div>
<p>
These flags control the additional output information:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a name="format_no_declaration"></a><code class="literal">format_no_declaration</code> disables
default node declaration output. By default, if the document is saved
via <code class="computeroutput"><span class="identifier">save</span></code> or <code class="computeroutput"><span class="identifier">save_file</span></code> function, and it does not
have any document declaration, a default declaration is output before
the document contents. Enabling this flag disables this declaration.
This flag has no effect in <code class="computeroutput"><span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span></code>
functions: they never output the default declaration. This flag is <span class="bold"><strong>off</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="format_write_bom"></a><code class="literal">format_write_bom</code> enables Byte Order
Mark (BOM) output. By default, no BOM is output, so in case of non UTF-8
encodings the resulting document's encoding may not be recognized by
some parsers and text editors, if they do not implement sophisticated
encoding detection. Enabling this flag adds an encoding-specific BOM
to the output. This flag has no effect in <code class="computeroutput"><span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span></code>
functions: they never output the BOM. This flag is <span class="bold"><strong>off</strong></span>
by default.
</li>
<li class="listitem">
<a name="format_save_file_text"></a><code class="literal">format_save_file_text</code> changes
the file mode when using <code class="computeroutput"><span class="identifier">save_file</span></code>
function. By default, file is opened in binary mode, which means that
the output file will contain platform-independent newline \n (ASCII 10).
If this flag is on, file is opened in text mode, which on some systems
changes the newline format (i.e. on Windows you can use this flag to
output XML documents with \r\n (ASCII 13 10) newlines. This flag is
<span class="bold"><strong>off</strong></span> by default.
</li>
</ul></div>
<p>
Additionally, there is one predefined option mask:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
<a name="format_default"></a><code class="literal">format_default</code> is the default set of
flags, i.e. it has all options set to their default values. It sets formatted
output with indentation, without BOM and with default node declaration,
if necessary.
</li></ul></div>
<p>
This is an example that shows the outputs of different output options (<a href="../samples/save_options.cpp" target="_top">samples/save_options.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// get a test document
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="string">"<foo bar='baz'><call>hey</call></foo>"</span><span class="special">);</span>
<span class="comment">// default options; prints
</span><span class="comment">// <?xml version="1.0"?>
</span><span class="comment">// <foo bar="baz">
</span><span class="comment">// <call>hey</call>
</span><span class="comment">// </foo>
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// default options with custom indentation string; prints
</span><span class="comment">// <?xml version="1.0"?>
</span><span class="comment">// <foo bar="baz">
</span><span class="comment">// --<call>hey</call>
</span><span class="comment">// </foo>
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">"--"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// default options without indentation; prints
</span><span class="comment">// <?xml version="1.0"?>
</span><span class="comment">// <foo bar="baz">
</span><span class="comment">// <call>hey</call>
</span><span class="comment">// </foo>
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">"\t"</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_default</span> <span class="special">&</span> <span class="special">~</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_indent</span><span class="special">);</span> <span class="comment">// can also pass "" instead of indentation string for the same effect
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// raw output; prints
</span><span class="comment">// <?xml version="1.0"?><foo bar="baz"><call>hey</call></foo>
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">"\t"</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// raw output without declaration; prints
</span><span class="comment">// <foo bar="baz"><call>hey</call></foo>
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">"\t"</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span> <span class="special">|</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_no_declaration</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.encoding"></a><a class="link" href="saving.html#manual.saving.encoding" title="Encodings"> Encodings</a>
</h3></div></div></div>
<p>
pugixml supports all popular Unicode encodings (UTF-8, UTF-16 (big and little
endian), UTF-32 (big and little endian); UCS-2 is naturally supported since
it's a strict subset of UTF-16) and handles all encoding conversions during
output. The output encoding is set via the <code class="computeroutput"><span class="identifier">encoding</span></code>
parameter of saving functions, which is of type <code class="computeroutput"><span class="identifier">xml_encoding</span></code>.
The possible values for the encoding are documented in <a class="xref" href="loading.html#manual.loading.encoding" title="Encodings"> Encodings</a>;
the only flag that has a different meaning is <code class="computeroutput"><span class="identifier">encoding_auto</span></code>.
</p>
<p>
While all other flags set the exact encoding, <code class="computeroutput"><span class="identifier">encoding_auto</span></code>
is meant for automatic encoding detection. The automatic detection does not
make sense for output encoding, since there is usually nothing to infer the
actual encoding from, so here <code class="computeroutput"><span class="identifier">encoding_auto</span></code>
means UTF-8 encoding, which is the most popular encoding for XML data storage.
This is also the default value of output encoding; specify another value
if you do not want UTF-8 encoded output.
</p>
<p>
Also note that wide stream saving functions do not have <code class="computeroutput"><span class="identifier">encoding</span></code>
argument and always assume <a class="link" href="loading.html#encoding_wchar">encoding_wchar</a>
encoding.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The current behavior for Unicode conversion is to skip all invalid UTF
sequences during conversion. This behavior should not be relied upon; if
your node/attribute names do not contain any valid UTF sequences, they
may be output as if they are empty, which will result in malformed XML
document.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.declaration"></a><a class="link" href="saving.html#manual.saving.declaration" title="Customizing document declaration"> Customizing document declaration</a>
</h3></div></div></div>
<p>
When you are saving the document using <code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save_file</span><span class="special">()</span></code>, a default XML document declaration is
output, if <code class="computeroutput"><span class="identifier">format_no_declaration</span></code>
is not specified and if the document does not have a declaration node. However,
the default declaration is not customizable. If you want to customize the
declaration output, you need to create the declaration node yourself.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
By default the declaration node is not added to the document during parsing.
If you just need to preserve the original declaration node, you have to
add the flag <a class="link" href="loading.html#parse_declaration">parse_declaration</a>
to the parsing flags; the resulting document will contain the original
declaration node, which will be output during saving.
</p></td></tr>
</table></div>
<p>
Declaration node is a node with type <a class="link" href="dom.html#node_declaration">node_declaration</a>;
it behaves like an element node in that it has attributes with values (but
it does not have child nodes). Therefore setting custom version, encoding
or standalone declaration involves adding attributes and setting attribute
values.
</p>
<p>
This is an example that shows how to create a custom declaration node (<a href="../samples/save_declaration.cpp" target="_top">samples/save_declaration.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// get a test document
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="string">"<foo bar='baz'><call>hey</call></foo>"</span><span class="special">);</span>
<span class="comment">// add a custom declaration node
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">decl</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">prepend_child</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">node_declaration</span><span class="special">);</span>
<span class="identifier">decl</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"version"</span><span class="special">)</span> <span class="special">=</span> <span class="string">"1.0"</span><span class="special">;</span>
<span class="identifier">decl</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"encoding"</span><span class="special">)</span> <span class="special">=</span> <span class="string">"UTF-8"</span><span class="special">;</span>
<span class="identifier">decl</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"standalone"</span><span class="special">)</span> <span class="special">=</span> <span class="string">"no"</span><span class="special">;</span>
<span class="comment">// <?xml version="1.0" encoding="UTF-8" standalone="no"?>
</span><span class="comment">// <foo bar="baz">
</span><span class="comment">// <call>hey</call>
</span><span class="comment">// </foo>
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> · <a href="loading.html">Loading</a> · <a href="access.html">Accessing</a> · <a href="modify.html">Modifying</a> · <b>Saving</b> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="modify.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="xpath.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
</body>
</html>
|