Coverage Report

Created: 2026-05-30 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pugixml/src/pugixml.hpp
Line
Count
Source
1
/**
2
 * pugixml parser - version 1.15
3
 * --------------------------------------------------------
4
 * Report bugs and download new versions at https://pugixml.org/
5
 *
6
 * SPDX-FileCopyrightText: Copyright (C) 2006-2026, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
7
 * SPDX-License-Identifier: MIT
8
 *
9
 * See LICENSE.md or notice at the end of this file.
10
 */
11
12
// Define version macro; evaluates to major * 1000 + minor * 10 + patch so that it's safe to use in less-than comparisons
13
// Note: pugixml used major * 100 + minor * 10 + patch format up until 1.9 (which had version identifier 190); starting from pugixml 1.10, the minor version number is two digits
14
#ifndef PUGIXML_VERSION
15
# define PUGIXML_VERSION 1150 // 1.15
16
#endif
17
18
// Include user configuration file (this can define various configuration macros)
19
#include "pugiconfig.hpp"
20
21
#ifndef HEADER_PUGIXML_HPP
22
#define HEADER_PUGIXML_HPP
23
24
// Include stddef.h for size_t and ptrdiff_t
25
#include <stddef.h>
26
27
// Include exception header for XPath
28
#if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS)
29
# include <exception>
30
#endif
31
32
// Include STL headers
33
#ifndef PUGIXML_NO_STL
34
# include <iterator>
35
# include <iosfwd>
36
# include <string>
37
#endif
38
39
// Check if std::string_view is available
40
#if !defined(PUGIXML_HAS_STRING_VIEW) && !defined(PUGIXML_NO_STL)
41
# if __cplusplus >= 201703L
42
#   define PUGIXML_HAS_STRING_VIEW
43
# elif defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
44
#   define PUGIXML_HAS_STRING_VIEW
45
# endif
46
#endif
47
48
// Include string_view if appropriate
49
#ifdef PUGIXML_HAS_STRING_VIEW
50
# include <string_view>
51
#endif
52
53
// Macro for deprecated features
54
#ifndef PUGIXML_DEPRECATED
55
# if defined(__GNUC__)
56
#   define PUGIXML_DEPRECATED __attribute__((deprecated))
57
# elif defined(_MSC_VER) && _MSC_VER >= 1300
58
#   define PUGIXML_DEPRECATED __declspec(deprecated)
59
# else
60
#   define PUGIXML_DEPRECATED
61
# endif
62
#endif
63
64
// If no API is defined, assume default
65
#ifndef PUGIXML_API
66
# define PUGIXML_API
67
#endif
68
69
// If no API for classes is defined, assume default
70
#ifndef PUGIXML_CLASS
71
# define PUGIXML_CLASS PUGIXML_API
72
#endif
73
74
// If no API for functions is defined, assume default
75
#ifndef PUGIXML_FUNCTION
76
# define PUGIXML_FUNCTION PUGIXML_API
77
#endif
78
79
// If the platform is known to have long long support, enable long long functions
80
#ifndef PUGIXML_HAS_LONG_LONG
81
# if __cplusplus >= 201103
82
#   define PUGIXML_HAS_LONG_LONG
83
# elif defined(_MSC_VER) && _MSC_VER >= 1400
84
#   define PUGIXML_HAS_LONG_LONG
85
# endif
86
#endif
87
88
// If the platform is known to have move semantics support, compile move ctor/operator implementation
89
#ifndef PUGIXML_HAS_MOVE
90
# if __cplusplus >= 201103
91
#   define PUGIXML_HAS_MOVE
92
# elif defined(_MSC_VER) && _MSC_VER >= 1600
93
#   define PUGIXML_HAS_MOVE
94
# endif
95
#endif
96
97
// If C++ is 2011 or higher, use 'noexcept' specifiers
98
#ifndef PUGIXML_NOEXCEPT
99
# if __cplusplus >= 201103
100
#   define PUGIXML_NOEXCEPT noexcept
101
# elif defined(_MSC_VER) && _MSC_VER >= 1900
102
#   define PUGIXML_NOEXCEPT noexcept
103
# else
104
#   define PUGIXML_NOEXCEPT throw()
105
# endif
106
#endif
107
108
// Some functions can not be noexcept in compact mode
109
#ifdef PUGIXML_COMPACT
110
# define PUGIXML_NOEXCEPT_IF_NOT_COMPACT
111
#else
112
# define PUGIXML_NOEXCEPT_IF_NOT_COMPACT PUGIXML_NOEXCEPT
113
#endif
114
115
// If C++ is 2011 or higher, add 'override' qualifiers
116
#ifndef PUGIXML_OVERRIDE
117
# if __cplusplus >= 201103
118
#   define PUGIXML_OVERRIDE override
119
# elif defined(_MSC_VER) && _MSC_VER >= 1700
120
#   define PUGIXML_OVERRIDE override
121
# else
122
#   define PUGIXML_OVERRIDE
123
# endif
124
#endif
125
126
// If C++ is 2011 or higher, use 'nullptr'
127
#ifndef PUGIXML_NULL
128
# if __cplusplus >= 201103
129
#   define PUGIXML_NULL nullptr
130
# elif defined(_MSC_VER) && _MSC_VER >= 1600
131
#   define PUGIXML_NULL nullptr
132
# else
133
#   define PUGIXML_NULL 0
134
# endif
135
#endif
136
137
// If C++ is 2017 or higher, add 'inline' variables
138
#ifndef PUGIXML_INLINE_VAR
139
# ifdef __cpp_inline_variables
140
#   define PUGIXML_INLINE_VAR inline
141
# else
142
#   define PUGIXML_INLINE_VAR
143
# endif
144
#endif
145
146
// Character interface macros
147
#ifdef PUGIXML_WCHAR_MODE
148
# define PUGIXML_TEXT(t) L ## t
149
# define PUGIXML_CHAR wchar_t
150
#else
151
223M
# define PUGIXML_TEXT(t) t
152
# define PUGIXML_CHAR char
153
#endif
154
155
namespace pugi
156
{
157
  // Character type used for all internal storage and operations; depends on PUGIXML_WCHAR_MODE
158
  typedef PUGIXML_CHAR char_t;
159
160
#ifndef PUGIXML_NO_STL
161
  // String type used for operations that work with STL string; depends on PUGIXML_WCHAR_MODE
162
  typedef std::basic_string<PUGIXML_CHAR> string_t;
163
#endif
164
165
#ifdef PUGIXML_HAS_STRING_VIEW
166
  // String view type used for operations that can work with a length delimited string; depends on PUGIXML_WCHAR_MODE
167
  typedef std::basic_string_view<PUGIXML_CHAR> string_view_t;
168
#endif
169
}
170
171
// The PugiXML namespace
172
namespace pugi
173
{
174
  // Tree node types
175
  enum xml_node_type
176
  {
177
    node_null,      // Empty (null) node handle
178
    node_document,    // A document tree's absolute root
179
    node_element,   // Element tag, i.e. '<node/>'
180
    node_pcdata,    // Plain character data, i.e. 'text'
181
    node_cdata,     // Character data, i.e. '<![CDATA[text]]>'
182
    node_comment,   // Comment tag, i.e. '<!-- text -->'
183
    node_pi,      // Processing instruction, i.e. '<?name?>'
184
    node_declaration, // Document declaration, i.e. '<?xml version="1.0"?>'
185
    node_doctype    // Document type declaration, i.e. '<!DOCTYPE doc>'
186
  };
187
188
  // Parsing options
189
190
  // Minimal parsing mode (equivalent to turning all other flags off).
191
  // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed.
192
  PUGIXML_INLINE_VAR const unsigned int parse_minimal = 0x0000;
193
194
  // This flag determines if processing instructions (node_pi) are added to the DOM tree. This flag is off by default.
195
  PUGIXML_INLINE_VAR const unsigned int parse_pi = 0x0001;
196
197
  // This flag determines if comments (node_comment) are added to the DOM tree. This flag is off by default.
198
  PUGIXML_INLINE_VAR const unsigned int parse_comments = 0x0002;
199
200
  // This flag determines if CDATA sections (node_cdata) are added to the DOM tree. This flag is on by default.
201
  PUGIXML_INLINE_VAR const unsigned int parse_cdata = 0x0004;
202
203
  // This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree.
204
  // This flag is off by default; turning it on usually results in slower parsing and more memory consumption.
205
  PUGIXML_INLINE_VAR const unsigned int parse_ws_pcdata = 0x0008;
206
207
  // This flag determines if character and entity references are expanded during parsing. This flag is on by default.
208
  PUGIXML_INLINE_VAR const unsigned int parse_escapes = 0x0010;
209
210
  // This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default.
211
  PUGIXML_INLINE_VAR const unsigned int parse_eol = 0x0020;
212
213
  // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default.
214
  PUGIXML_INLINE_VAR const unsigned int parse_wconv_attribute = 0x0040;
215
216
  // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default.
217
  PUGIXML_INLINE_VAR const unsigned int parse_wnorm_attribute = 0x0080;
218
219
  // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default.
220
  PUGIXML_INLINE_VAR const unsigned int parse_declaration = 0x0100;
221
222
  // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default.
223
  PUGIXML_INLINE_VAR const unsigned int parse_doctype = 0x0200;
224
225
  // This flag determines if plain character data (node_pcdata) that is the only child of the parent node and that consists only
226
  // of whitespace is added to the DOM tree.
227
  // This flag is off by default; turning it on may result in slower parsing and more memory consumption.
228
  PUGIXML_INLINE_VAR const unsigned int parse_ws_pcdata_single = 0x0400;
229
230
  // This flag determines if leading and trailing whitespace is to be removed from plain character data. This flag is off by default.
231
  PUGIXML_INLINE_VAR const unsigned int parse_trim_pcdata = 0x0800;
232
233
  // This flag determines if plain character data that does not have a parent node is added to the DOM tree, and if an empty document
234
  // is a valid document. This flag is off by default.
235
  PUGIXML_INLINE_VAR const unsigned int parse_fragment = 0x1000;
236
237
  // This flag determines if plain character data is be stored in the parent element's value. This significantly changes the structure of
238
  // the document; this flag is only recommended for parsing documents with many PCDATA nodes in memory-constrained environments.
239
  // This flag is off by default.
240
  PUGIXML_INLINE_VAR const unsigned int parse_embed_pcdata = 0x2000;
241
242
  // This flag determines whether determines whether the the two pcdata should be merged or not, if no intermediatory data are parsed in the document.
243
  // This flag is off by default.
244
  PUGIXML_INLINE_VAR const unsigned int parse_merge_pcdata = 0x4000;
245
246
  // The default parsing mode.
247
  // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded,
248
  // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules.
249
  PUGIXML_INLINE_VAR const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol;
250
251
  // The full parsing mode.
252
  // Nodes of all types are added to the DOM tree, character/reference entities are expanded,
253
  // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules.
254
  PUGIXML_INLINE_VAR const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype;
255
256
  // These flags determine the encoding of input data for XML document
257
  enum xml_encoding
258
  {
259
    encoding_auto,    // Auto-detect input encoding using BOM or < / <? detection; use UTF8 if BOM is not found
260
    encoding_utf8,    // UTF8 encoding
261
    encoding_utf16_le,  // Little-endian UTF16
262
    encoding_utf16_be,  // Big-endian UTF16
263
    encoding_utf16,   // UTF16 with native endianness
264
    encoding_utf32_le,  // Little-endian UTF32
265
    encoding_utf32_be,  // Big-endian UTF32
266
    encoding_utf32,   // UTF32 with native endianness
267
    encoding_wchar,   // The same encoding wchar_t has (either UTF16 or UTF32)
268
    encoding_latin1
269
  };
270
271
  // Formatting flags
272
273
  // Indent the nodes that are written to output stream with as many indentation strings as deep the node is in DOM tree. This flag is on by default.
274
  PUGIXML_INLINE_VAR const unsigned int format_indent = 0x01;
275
276
  // Write encoding-specific BOM to the output stream. This flag is off by default.
277
  PUGIXML_INLINE_VAR const unsigned int format_write_bom = 0x02;
278
279
  // Use raw output mode (no indentation and no line breaks are written). This flag is off by default.
280
  PUGIXML_INLINE_VAR const unsigned int format_raw = 0x04;
281
282
  // Omit default XML declaration even if there is no declaration in the document. This flag is off by default.
283
  PUGIXML_INLINE_VAR const unsigned int format_no_declaration = 0x08;
284
285
  // Don't escape attribute values and PCDATA contents. This flag is off by default.
286
  PUGIXML_INLINE_VAR const unsigned int format_no_escapes = 0x10;
287
288
  // Open file using text mode in xml_document::save_file. This enables special character (i.e. new-line) conversions on some systems. This flag is off by default.
289
  PUGIXML_INLINE_VAR const unsigned int format_save_file_text = 0x20;
290
291
  // Write every attribute on a new line with appropriate indentation. This flag is off by default.
292
  PUGIXML_INLINE_VAR const unsigned int format_indent_attributes = 0x40;
293
294
  // Don't output empty element tags, instead writing an explicit start and end tag even if there are no children. This flag is off by default.
295
  PUGIXML_INLINE_VAR const unsigned int format_no_empty_element_tags = 0x80;
296
297
  // Skip characters belonging to range [0; 32) instead of "&#xNN;" encoding. This flag is off by default.
298
  PUGIXML_INLINE_VAR const unsigned int format_skip_control_chars = 0x100;
299
300
  // Use single quotes ' instead of double quotes " for enclosing attribute values. This flag is off by default.
301
  PUGIXML_INLINE_VAR const unsigned int format_attribute_single_quote = 0x200;
302
303
  // The default set of formatting flags.
304
  // Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none.
305
  PUGIXML_INLINE_VAR const unsigned int format_default = format_indent;
306
307
  PUGIXML_INLINE_VAR const int default_double_precision = 17;
308
  PUGIXML_INLINE_VAR const int default_float_precision = 9;
309
310
  // Forward declarations
311
  struct xml_attribute_struct;
312
  struct xml_node_struct;
313
314
  class xml_node_iterator;
315
  class xml_attribute_iterator;
316
  class xml_named_node_iterator;
317
318
  class xml_tree_walker;
319
320
  struct xml_parse_result;
321
322
  class xml_node;
323
324
  class xml_text;
325
326
  #ifndef PUGIXML_NO_XPATH
327
  class xpath_node;
328
  class xpath_node_set;
329
  class xpath_query;
330
  class xpath_variable_set;
331
  #endif
332
333
  // Range-based for loop support
334
  template <typename It> class xml_object_range
335
  {
336
  public:
337
    typedef It const_iterator;
338
    typedef It iterator;
339
340
0
    xml_object_range(It b, It e): _begin(b), _end(e)
341
0
    {
342
0
    }
Unexecuted instantiation: pugi::xml_object_range<pugi::xml_node_iterator>::xml_object_range(pugi::xml_node_iterator, pugi::xml_node_iterator)
Unexecuted instantiation: pugi::xml_object_range<pugi::xml_named_node_iterator>::xml_object_range(pugi::xml_named_node_iterator, pugi::xml_named_node_iterator)
Unexecuted instantiation: pugi::xml_object_range<pugi::xml_attribute_iterator>::xml_object_range(pugi::xml_attribute_iterator, pugi::xml_attribute_iterator)
343
344
    It begin() const { return _begin; }
345
    It end() const { return _end; }
346
347
    bool empty() const { return _begin == _end; }
348
349
  private:
350
    It _begin, _end;
351
  };
352
353
  // Writer interface for node printing (see xml_node::print)
354
  class PUGIXML_CLASS xml_writer
355
  {
356
  public:
357
    virtual ~xml_writer();
358
359
    // Write memory chunk into stream/file/whatever
360
    virtual void write(const void* data, size_t size) = 0;
361
  };
362
363
  // xml_writer implementation for FILE*
364
  class PUGIXML_CLASS xml_writer_file: public xml_writer
365
  {
366
  public:
367
    // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio
368
    xml_writer_file(void* file);
369
370
    virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE;
371
372
  private:
373
    void* file;
374
  };
375
376
  #ifndef PUGIXML_NO_STL
377
  // xml_writer implementation for streams
378
  class PUGIXML_CLASS xml_writer_stream: public xml_writer
379
  {
380
  public:
381
    // Construct writer from an output stream object
382
    xml_writer_stream(std::basic_ostream<char>& stream);
383
    xml_writer_stream(std::basic_ostream<wchar_t>& stream);
384
385
    virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE;
386
387
  private:
388
    std::basic_ostream<char>* narrow_stream;
389
    std::basic_ostream<wchar_t>* wide_stream;
390
  };
391
  #endif
392
393
  // A light-weight handle for manipulating attributes in DOM tree
394
  class PUGIXML_CLASS xml_attribute
395
  {
396
    friend class xml_attribute_iterator;
397
    friend class xml_node;
398
399
  private:
400
    xml_attribute_struct* _attr;
401
402
    typedef void (*unspecified_bool_type)(xml_attribute***);
403
404
  public:
405
    // Default constructor. Constructs an empty attribute.
406
    xml_attribute();
407
408
    // Constructs attribute from internal pointer
409
    explicit xml_attribute(xml_attribute_struct* attr);
410
411
    // Safe bool conversion operator
412
    operator unspecified_bool_type() const;
413
414
    // Borland C++ workaround
415
    bool operator!() const;
416
417
    // Comparison operators (compares wrapped attribute pointers)
418
    bool operator==(const xml_attribute& r) const;
419
    bool operator!=(const xml_attribute& r) const;
420
    bool operator<(const xml_attribute& r) const;
421
    bool operator>(const xml_attribute& r) const;
422
    bool operator<=(const xml_attribute& r) const;
423
    bool operator>=(const xml_attribute& r) const;
424
425
    // Check if attribute is empty (null)
426
    bool empty() const;
427
428
    // Get attribute name/value, or "" if attribute is empty
429
    const char_t* name() const;
430
    const char_t* value() const;
431
432
    // Get attribute value, or the default value if attribute is empty
433
    const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const;
434
435
    // Get attribute value as a number, or the default value if conversion did not succeed or attribute is empty
436
    int as_int(int def = 0) const;
437
    unsigned int as_uint(unsigned int def = 0) const;
438
    double as_double(double def = 0) const;
439
    float as_float(float def = 0) const;
440
441
  #ifdef PUGIXML_HAS_LONG_LONG
442
    long long as_llong(long long def = 0) const;
443
    unsigned long long as_ullong(unsigned long long def = 0) const;
444
  #endif
445
446
    // Get attribute value as bool (returns true if first character is in '1tTyY' set), or the default value if attribute is empty
447
    bool as_bool(bool def = false) const;
448
449
    // Set attribute name/value (returns false if attribute is empty or there is not enough memory)
450
    bool set_name(const char_t* rhs);
451
    bool set_name(const char_t* rhs, size_t size);
452
  #ifdef PUGIXML_HAS_STRING_VIEW
453
    bool set_name(string_view_t rhs);
454
  #endif
455
    bool set_value(const char_t* rhs);
456
    bool set_value(const char_t* rhs, size_t size);
457
  #ifdef PUGIXML_HAS_STRING_VIEW
458
    bool set_value(string_view_t rhs);
459
  #endif
460
461
    // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false")
462
    bool set_value(int rhs);
463
    bool set_value(unsigned int rhs);
464
    bool set_value(long rhs);
465
    bool set_value(unsigned long rhs);
466
    bool set_value(double rhs);
467
    bool set_value(double rhs, int precision);
468
    bool set_value(float rhs);
469
    bool set_value(float rhs, int precision);
470
    bool set_value(bool rhs);
471
472
  #ifdef PUGIXML_HAS_LONG_LONG
473
    bool set_value(long long rhs);
474
    bool set_value(unsigned long long rhs);
475
  #endif
476
477
    // Set attribute value (equivalent to set_value without error checking)
478
    xml_attribute& operator=(const char_t* rhs);
479
    xml_attribute& operator=(int rhs);
480
    xml_attribute& operator=(unsigned int rhs);
481
    xml_attribute& operator=(long rhs);
482
    xml_attribute& operator=(unsigned long rhs);
483
    xml_attribute& operator=(double rhs);
484
    xml_attribute& operator=(float rhs);
485
    xml_attribute& operator=(bool rhs);
486
487
  #ifdef PUGIXML_HAS_STRING_VIEW
488
    xml_attribute& operator=(string_view_t rhs);
489
  #endif
490
491
  #ifdef PUGIXML_HAS_LONG_LONG
492
    xml_attribute& operator=(long long rhs);
493
    xml_attribute& operator=(unsigned long long rhs);
494
  #endif
495
496
    // Get next/previous attribute in the attribute list of the parent node
497
    xml_attribute next_attribute() const;
498
    xml_attribute previous_attribute() const;
499
500
    // Get hash value (unique for handles to the same object)
501
    size_t hash_value() const;
502
503
    // Get internal pointer
504
    xml_attribute_struct* internal_object() const;
505
  };
506
507
#ifdef __BORLANDC__
508
  // Borland C++ workaround
509
  bool PUGIXML_FUNCTION operator&&(const xml_attribute& lhs, bool rhs);
510
  bool PUGIXML_FUNCTION operator||(const xml_attribute& lhs, bool rhs);
511
#endif
512
513
  // A light-weight handle for manipulating nodes in DOM tree
514
  class PUGIXML_CLASS xml_node
515
  {
516
    friend class xml_attribute_iterator;
517
    friend class xml_node_iterator;
518
    friend class xml_named_node_iterator;
519
520
  protected:
521
    xml_node_struct* _root;
522
523
    typedef void (*unspecified_bool_type)(xml_node***);
524
525
  public:
526
    // Default constructor. Constructs an empty node.
527
    xml_node();
528
529
    // Constructs node from internal pointer
530
    explicit xml_node(xml_node_struct* p);
531
532
    // Safe bool conversion operator
533
    operator unspecified_bool_type() const;
534
535
    // Borland C++ workaround
536
    bool operator!() const;
537
538
    // Comparison operators (compares wrapped node pointers)
539
    bool operator==(const xml_node& r) const;
540
    bool operator!=(const xml_node& r) const;
541
    bool operator<(const xml_node& r) const;
542
    bool operator>(const xml_node& r) const;
543
    bool operator<=(const xml_node& r) const;
544
    bool operator>=(const xml_node& r) const;
545
546
    // Check if node is empty (null)
547
    bool empty() const;
548
549
    // Get node type
550
    xml_node_type type() const;
551
552
    // Get node name, or "" if node is empty or it has no name
553
    const char_t* name() const;
554
555
    // Get node value, or "" if node is empty or it has no value
556
    // Note: For <node>text</node> node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes.
557
    const char_t* value() const;
558
559
    // Get attribute list
560
    xml_attribute first_attribute() const;
561
    xml_attribute last_attribute() const;
562
563
    // Get children list
564
    xml_node first_child() const;
565
    xml_node last_child() const;
566
567
    // Get next/previous sibling in the children list of the parent node
568
    xml_node next_sibling() const;
569
    xml_node previous_sibling() const;
570
571
    // Get parent node
572
    xml_node parent() const;
573
574
    // Get root of DOM tree this node belongs to
575
    xml_node root() const;
576
577
    // Get text object for the current node
578
    xml_text text() const;
579
580
    // Get child, attribute or next/previous sibling with the specified name
581
    xml_node child(const char_t* name) const;
582
    xml_attribute attribute(const char_t* name) const;
583
    xml_node next_sibling(const char_t* name) const;
584
    xml_node previous_sibling(const char_t* name) const;
585
  #ifdef PUGIXML_HAS_STRING_VIEW
586
    xml_node child(string_view_t name) const;
587
    xml_attribute attribute(string_view_t name) const;
588
    xml_node next_sibling(string_view_t name) const;
589
    xml_node previous_sibling(string_view_t name) const;
590
  #endif
591
592
    // Get attribute, starting the search from a hint (and updating hint so that searching for a sequence of attributes is fast)
593
    xml_attribute attribute(const char_t* name, xml_attribute& hint) const;
594
  #ifdef PUGIXML_HAS_STRING_VIEW
595
    xml_attribute attribute(string_view_t name, xml_attribute& hint) const;
596
  #endif
597
598
    // Get child value of current node; that is, value of the first child node of type PCDATA/CDATA
599
    const char_t* child_value() const;
600
601
    // Get child value of child with specified name. Equivalent to child(name).child_value().
602
    const char_t* child_value(const char_t* name) const;
603
604
    // Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value)
605
    bool set_name(const char_t* rhs);
606
    bool set_name(const char_t* rhs, size_t size);
607
  #ifdef PUGIXML_HAS_STRING_VIEW
608
    bool set_name(string_view_t rhs);
609
  #endif
610
    bool set_value(const char_t* rhs);
611
    bool set_value(const char_t* rhs, size_t size);
612
  #ifdef PUGIXML_HAS_STRING_VIEW
613
    bool set_value(string_view_t rhs);
614
  #endif
615
616
    // Add attribute with specified name. Returns added attribute, or empty attribute on errors.
617
    xml_attribute append_attribute(const char_t* name);
618
    xml_attribute prepend_attribute(const char_t* name);
619
    xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr);
620
    xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr);
621
  #ifdef PUGIXML_HAS_STRING_VIEW
622
    xml_attribute append_attribute(string_view_t name);
623
    xml_attribute prepend_attribute(string_view_t name);
624
    xml_attribute insert_attribute_after(string_view_t name, const xml_attribute& attr);
625
    xml_attribute insert_attribute_before(string_view_t name, const xml_attribute& attr);
626
  #endif
627
628
    // Add a copy of the specified attribute. Returns added attribute, or empty attribute on errors.
629
    xml_attribute append_copy(const xml_attribute& proto);
630
    xml_attribute prepend_copy(const xml_attribute& proto);
631
    xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr);
632
    xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr);
633
634
    // Add child node with specified type. Returns added node, or empty node on errors.
635
    xml_node append_child(xml_node_type type = node_element);
636
    xml_node prepend_child(xml_node_type type = node_element);
637
    xml_node insert_child_after(xml_node_type type, const xml_node& node);
638
    xml_node insert_child_before(xml_node_type type, const xml_node& node);
639
640
    // Add child element with specified name. Returns added node, or empty node on errors.
641
    xml_node append_child(const char_t* name);
642
    xml_node prepend_child(const char_t* name);
643
    xml_node insert_child_after(const char_t* name, const xml_node& node);
644
    xml_node insert_child_before(const char_t* name, const xml_node& node);
645
  #ifdef PUGIXML_HAS_STRING_VIEW
646
    xml_node append_child(string_view_t name);
647
    xml_node prepend_child(string_view_t name);
648
    xml_node insert_child_after(string_view_t, const xml_node& node);
649
    xml_node insert_child_before(string_view_t name, const xml_node& node);
650
  #endif
651
652
    // Add a copy of the specified node as a child. Returns added node, or empty node on errors.
653
    xml_node append_copy(const xml_node& proto);
654
    xml_node prepend_copy(const xml_node& proto);
655
    xml_node insert_copy_after(const xml_node& proto, const xml_node& node);
656
    xml_node insert_copy_before(const xml_node& proto, const xml_node& node);
657
658
    // Move the specified node to become a child of this node. Returns moved node, or empty node on errors.
659
    xml_node append_move(const xml_node& moved);
660
    xml_node prepend_move(const xml_node& moved);
661
    xml_node insert_move_after(const xml_node& moved, const xml_node& node);
662
    xml_node insert_move_before(const xml_node& moved, const xml_node& node);
663
664
    // Remove specified attribute
665
    bool remove_attribute(const xml_attribute& a);
666
    bool remove_attribute(const char_t* name);
667
  #ifdef PUGIXML_HAS_STRING_VIEW
668
    bool remove_attribute(string_view_t name);
669
  #endif
670
671
    // Remove all attributes
672
    bool remove_attributes();
673
674
    // Remove specified child
675
    bool remove_child(const xml_node& n);
676
    bool remove_child(const char_t* name);
677
  #ifdef PUGIXML_HAS_STRING_VIEW
678
    bool remove_child(string_view_t name);
679
  #endif
680
681
    // Remove all children
682
    bool remove_children();
683
684
    // Parses buffer as an XML document fragment and appends all nodes as children of the current node.
685
    // Copies/converts the buffer, so it may be deleted or changed after the function returns.
686
    // Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory.
687
    xml_parse_result append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
688
689
    // Find attribute using predicate. Returns first attribute for which predicate returned true.
690
    template <typename Predicate> xml_attribute find_attribute(Predicate pred) const
691
38.4k
    {
692
38.4k
      if (!_root) return xml_attribute();
693
694
47.0k
      for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute())
695
10.2k
        if (pred(attrib))
696
1.63k
          return attrib;
697
698
36.7k
      return xml_attribute();
699
38.4k
    }
700
701
    // Find child node using predicate. Returns first child for which predicate returned true.
702
    template <typename Predicate> xml_node find_child(Predicate pred) const
703
    {
704
      if (!_root) return xml_node();
705
706
      for (xml_node node = first_child(); node; node = node.next_sibling())
707
        if (pred(node))
708
          return node;
709
710
      return xml_node();
711
    }
712
713
    // Find node from subtree using predicate. Returns first node from subtree (depth-first), for which predicate returned true.
714
    template <typename Predicate> xml_node find_node(Predicate pred) const
715
    {
716
      if (!_root) return xml_node();
717
718
      xml_node cur = first_child();
719
720
      while (cur._root && cur._root != _root)
721
      {
722
        if (pred(cur)) return cur;
723
724
        if (cur.first_child()) cur = cur.first_child();
725
        else if (cur.next_sibling()) cur = cur.next_sibling();
726
        else
727
        {
728
          while (!cur.next_sibling() && cur._root != _root) cur = cur.parent();
729
730
          if (cur._root != _root) cur = cur.next_sibling();
731
        }
732
      }
733
734
      return xml_node();
735
    }
736
737
    // Find child node by attribute name/value
738
    xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
739
    xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const;
740
741
  #ifndef PUGIXML_NO_STL
742
    // Get the absolute node path from root as a text string.
743
    string_t path(char_t delimiter = '/') const;
744
  #endif
745
746
    // Search for a node by path consisting of node names and . or .. elements.
747
    xml_node first_element_by_path(const char_t* path, char_t delimiter = '/') const;
748
749
    // Recursively traverse subtree with xml_tree_walker
750
    bool traverse(xml_tree_walker& walker);
751
752
  #ifndef PUGIXML_NO_XPATH
753
    // Select single node by evaluating XPath query. Returns first node from the resulting node set.
754
    xpath_node select_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const;
755
    xpath_node select_node(const xpath_query& query) const;
756
757
    // Select node set by evaluating XPath query
758
    xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const;
759
    xpath_node_set select_nodes(const xpath_query& query) const;
760
761
    // (deprecated: use select_node instead) Select single node by evaluating XPath query.
762
    PUGIXML_DEPRECATED xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const;
763
    PUGIXML_DEPRECATED xpath_node select_single_node(const xpath_query& query) const;
764
765
  #endif
766
767
    // Print subtree using a writer object
768
    void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
769
770
  #ifndef PUGIXML_NO_STL
771
    // Print subtree to stream
772
    void print(std::basic_ostream<char>& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
773
    void print(std::basic_ostream<wchar_t>& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const;
774
  #endif
775
776
    // Child nodes iterators
777
    typedef xml_node_iterator iterator;
778
779
    iterator begin() const;
780
    iterator end() const;
781
782
    // Attribute iterators
783
    typedef xml_attribute_iterator attribute_iterator;
784
785
    attribute_iterator attributes_begin() const;
786
    attribute_iterator attributes_end() const;
787
788
    // Range-based for support
789
    xml_object_range<xml_node_iterator> children() const;
790
    xml_object_range<xml_attribute_iterator> attributes() const;
791
792
    // Range-based for support for all children with the specified name
793
    // Note: name pointer must have a longer lifetime than the returned object; be careful with passing temporaries!
794
    xml_object_range<xml_named_node_iterator> children(const char_t* name) const;
795
796
    // Get node offset in parsed file/string (in char_t units) for debugging purposes
797
    ptrdiff_t offset_debug() const;
798
799
    // Get hash value (unique for handles to the same object)
800
    size_t hash_value() const;
801
802
    // Get internal pointer
803
    xml_node_struct* internal_object() const;
804
  };
805
806
#ifdef __BORLANDC__
807
  // Borland C++ workaround
808
  bool PUGIXML_FUNCTION operator&&(const xml_node& lhs, bool rhs);
809
  bool PUGIXML_FUNCTION operator||(const xml_node& lhs, bool rhs);
810
#endif
811
812
  // A helper for working with text inside PCDATA nodes
813
  class PUGIXML_CLASS xml_text
814
  {
815
    friend class xml_node;
816
817
    xml_node_struct* _root;
818
819
    typedef void (*unspecified_bool_type)(xml_text***);
820
821
    explicit xml_text(xml_node_struct* root);
822
823
    xml_node_struct* _data_new();
824
    xml_node_struct* _data() const;
825
826
  public:
827
    // Default constructor. Constructs an empty object.
828
    xml_text();
829
830
    // Safe bool conversion operator
831
    operator unspecified_bool_type() const;
832
833
    // Borland C++ workaround
834
    bool operator!() const;
835
836
    // Check if text object is empty (null)
837
    bool empty() const;
838
839
    // Get text, or "" if object is empty
840
    const char_t* get() const;
841
842
    // Get text, or the default value if object is empty
843
    const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const;
844
845
    // Get text as a number, or the default value if conversion did not succeed or object is empty
846
    int as_int(int def = 0) const;
847
    unsigned int as_uint(unsigned int def = 0) const;
848
    double as_double(double def = 0) const;
849
    float as_float(float def = 0) const;
850
851
  #ifdef PUGIXML_HAS_LONG_LONG
852
    long long as_llong(long long def = 0) const;
853
    unsigned long long as_ullong(unsigned long long def = 0) const;
854
  #endif
855
856
    // Get text as bool (returns true if first character is in '1tTyY' set), or the default value if object is empty
857
    bool as_bool(bool def = false) const;
858
859
    // Set text (returns false if object is empty or there is not enough memory)
860
    bool set(const char_t* rhs);
861
    bool set(const char_t* rhs, size_t size);
862
  #ifdef PUGIXML_HAS_STRING_VIEW
863
    bool set(string_view_t rhs);
864
  #endif
865
866
    // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false")
867
    bool set(int rhs);
868
    bool set(unsigned int rhs);
869
    bool set(long rhs);
870
    bool set(unsigned long rhs);
871
    bool set(double rhs);
872
    bool set(double rhs, int precision);
873
    bool set(float rhs);
874
    bool set(float rhs, int precision);
875
    bool set(bool rhs);
876
877
  #ifdef PUGIXML_HAS_LONG_LONG
878
    bool set(long long rhs);
879
    bool set(unsigned long long rhs);
880
  #endif
881
882
    // Set text (equivalent to set without error checking)
883
    xml_text& operator=(const char_t* rhs);
884
    xml_text& operator=(int rhs);
885
    xml_text& operator=(unsigned int rhs);
886
    xml_text& operator=(long rhs);
887
    xml_text& operator=(unsigned long rhs);
888
    xml_text& operator=(double rhs);
889
    xml_text& operator=(float rhs);
890
    xml_text& operator=(bool rhs);
891
892
  #ifdef PUGIXML_HAS_STRING_VIEW
893
    xml_text& operator=(string_view_t rhs);
894
  #endif
895
896
  #ifdef PUGIXML_HAS_LONG_LONG
897
    xml_text& operator=(long long rhs);
898
    xml_text& operator=(unsigned long long rhs);
899
  #endif
900
901
    // Get the data node (node_pcdata or node_cdata) for this object
902
    xml_node data() const;
903
  };
904
905
#ifdef __BORLANDC__
906
  // Borland C++ workaround
907
  bool PUGIXML_FUNCTION operator&&(const xml_text& lhs, bool rhs);
908
  bool PUGIXML_FUNCTION operator||(const xml_text& lhs, bool rhs);
909
#endif
910
911
  // Child node iterator (a bidirectional iterator over a collection of xml_node)
912
  class PUGIXML_CLASS xml_node_iterator
913
  {
914
    friend class xml_node;
915
916
  private:
917
    mutable xml_node _wrap;
918
    xml_node _parent;
919
920
    xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent);
921
922
  public:
923
    // Iterator traits
924
    typedef ptrdiff_t difference_type;
925
    typedef xml_node value_type;
926
    typedef xml_node* pointer;
927
    typedef xml_node& reference;
928
929
  #ifndef PUGIXML_NO_STL
930
    typedef std::bidirectional_iterator_tag iterator_category;
931
  #endif
932
933
    // Default constructor
934
    xml_node_iterator();
935
936
    // Construct an iterator which points to the specified node
937
    xml_node_iterator(const xml_node& node);
938
939
    // Iterator operators
940
    bool operator==(const xml_node_iterator& rhs) const;
941
    bool operator!=(const xml_node_iterator& rhs) const;
942
943
    xml_node& operator*() const;
944
    xml_node* operator->() const;
945
946
    xml_node_iterator& operator++();
947
    xml_node_iterator operator++(int);
948
949
    xml_node_iterator& operator--();
950
    xml_node_iterator operator--(int);
951
  };
952
953
  // Attribute iterator (a bidirectional iterator over a collection of xml_attribute)
954
  class PUGIXML_CLASS xml_attribute_iterator
955
  {
956
    friend class xml_node;
957
958
  private:
959
    mutable xml_attribute _wrap;
960
    xml_node _parent;
961
962
    xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent);
963
964
  public:
965
    // Iterator traits
966
    typedef ptrdiff_t difference_type;
967
    typedef xml_attribute value_type;
968
    typedef xml_attribute* pointer;
969
    typedef xml_attribute& reference;
970
971
  #ifndef PUGIXML_NO_STL
972
    typedef std::bidirectional_iterator_tag iterator_category;
973
  #endif
974
975
    // Default constructor
976
    xml_attribute_iterator();
977
978
    // Construct an iterator which points to the specified attribute
979
    xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent);
980
981
    // Iterator operators
982
    bool operator==(const xml_attribute_iterator& rhs) const;
983
    bool operator!=(const xml_attribute_iterator& rhs) const;
984
985
    xml_attribute& operator*() const;
986
    xml_attribute* operator->() const;
987
988
    xml_attribute_iterator& operator++();
989
    xml_attribute_iterator operator++(int);
990
991
    xml_attribute_iterator& operator--();
992
    xml_attribute_iterator operator--(int);
993
  };
994
995
  // Named node range helper
996
  class PUGIXML_CLASS xml_named_node_iterator
997
  {
998
    friend class xml_node;
999
1000
  public:
1001
    // Iterator traits
1002
    typedef ptrdiff_t difference_type;
1003
    typedef xml_node value_type;
1004
    typedef xml_node* pointer;
1005
    typedef xml_node& reference;
1006
1007
  #ifndef PUGIXML_NO_STL
1008
    typedef std::bidirectional_iterator_tag iterator_category;
1009
  #endif
1010
1011
    // Default constructor
1012
    xml_named_node_iterator();
1013
1014
    // Construct an iterator which points to the specified node
1015
    // Note: name pointer is stored in the iterator and must have a longer lifetime than iterator itself
1016
    xml_named_node_iterator(const xml_node& node, const char_t* name);
1017
1018
    // Iterator operators
1019
    bool operator==(const xml_named_node_iterator& rhs) const;
1020
    bool operator!=(const xml_named_node_iterator& rhs) const;
1021
1022
    xml_node& operator*() const;
1023
    xml_node* operator->() const;
1024
1025
    xml_named_node_iterator& operator++();
1026
    xml_named_node_iterator operator++(int);
1027
1028
    xml_named_node_iterator& operator--();
1029
    xml_named_node_iterator operator--(int);
1030
1031
  private:
1032
    mutable xml_node _wrap;
1033
    xml_node _parent;
1034
    const char_t* _name;
1035
1036
    xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name);
1037
  };
1038
1039
  // Abstract tree walker class (see xml_node::traverse)
1040
  class PUGIXML_CLASS xml_tree_walker
1041
  {
1042
    friend class xml_node;
1043
1044
  private:
1045
    int _depth;
1046
1047
  protected:
1048
    // Get current traversal depth
1049
    int depth() const;
1050
1051
  public:
1052
    xml_tree_walker();
1053
    virtual ~xml_tree_walker();
1054
1055
    // Callback that is called when traversal begins
1056
    virtual bool begin(xml_node& node);
1057
1058
    // Callback that is called for each node traversed
1059
    virtual bool for_each(xml_node& node) = 0;
1060
1061
    // Callback that is called when traversal ends
1062
    virtual bool end(xml_node& node);
1063
  };
1064
1065
  // Parsing status, returned as part of xml_parse_result object
1066
  enum xml_parse_status
1067
  {
1068
    status_ok = 0,        // No error
1069
1070
    status_file_not_found,    // File was not found during load_file()
1071
    status_io_error,      // Error reading from file/stream
1072
    status_out_of_memory,   // Could not allocate memory
1073
    status_internal_error,    // Internal error occurred
1074
1075
    status_unrecognized_tag,  // Parser could not determine tag type
1076
1077
    status_bad_pi,        // Parsing error occurred while parsing document declaration/processing instruction
1078
    status_bad_comment,     // Parsing error occurred while parsing comment
1079
    status_bad_cdata,     // Parsing error occurred while parsing CDATA section
1080
    status_bad_doctype,     // Parsing error occurred while parsing document type declaration
1081
    status_bad_pcdata,      // Parsing error occurred while parsing PCDATA section
1082
    status_bad_start_element, // Parsing error occurred while parsing start element tag
1083
    status_bad_attribute,   // Parsing error occurred while parsing element attribute
1084
    status_bad_end_element,   // Parsing error occurred while parsing end element tag
1085
    status_end_element_mismatch,// There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag)
1086
1087
    status_append_invalid_root, // Unable to append nodes since root type is not node_element or node_document (exclusive to xml_node::append_buffer)
1088
1089
    status_no_document_element  // Parsing resulted in a document without element nodes
1090
  };
1091
1092
  // Parsing result
1093
  struct PUGIXML_CLASS xml_parse_result
1094
  {
1095
    // Parsing status (see xml_parse_status)
1096
    xml_parse_status status;
1097
1098
    // Last parsed offset (in char_t units from start of input data)
1099
    ptrdiff_t offset;
1100
1101
    // Source document encoding
1102
    xml_encoding encoding;
1103
1104
    // Default constructor, initializes object to failed state
1105
    xml_parse_result();
1106
1107
    // Cast to bool operator
1108
    operator bool() const;
1109
1110
    // Get error description
1111
    const char* description() const;
1112
  };
1113
1114
  // Document class (DOM tree root)
1115
  class PUGIXML_CLASS xml_document: public xml_node
1116
  {
1117
  private:
1118
    char_t* _buffer;
1119
1120
    char _memory[192];
1121
1122
    // Non-copyable semantics
1123
    xml_document(const xml_document&);
1124
    xml_document& operator=(const xml_document&);
1125
1126
    void _create();
1127
    void _destroy();
1128
    void _move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT;
1129
1130
  public:
1131
    // Default constructor, makes empty document
1132
    xml_document();
1133
1134
    // Destructor, invalidates all node/attribute handles to this document
1135
    ~xml_document();
1136
1137
  #ifdef PUGIXML_HAS_MOVE
1138
    // Move semantics support
1139
    xml_document(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT;
1140
    xml_document& operator=(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT;
1141
  #endif
1142
1143
    // Removes all nodes, leaving the empty document
1144
    void reset();
1145
1146
    // Removes all nodes, then copies the entire contents of the specified document
1147
    void reset(const xml_document& proto);
1148
1149
  #ifndef PUGIXML_NO_STL
1150
    // Load document from stream.
1151
    xml_parse_result load(std::basic_istream<char>& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
1152
    xml_parse_result load(std::basic_istream<wchar_t>& stream, unsigned int options = parse_default);
1153
  #endif
1154
1155
    // (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied.
1156
    PUGIXML_DEPRECATED xml_parse_result load(const char_t* contents, unsigned int options = parse_default);
1157
1158
    // Load document from zero-terminated string. No encoding conversions are applied.
1159
    xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default);
1160
1161
    // Load document from file
1162
    xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
1163
    xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
1164
1165
    // Load document from buffer. Copies/converts the buffer, so it may be deleted or changed after the function returns.
1166
    xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
1167
1168
    // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data).
1169
    // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed.
1170
    xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
1171
1172
    // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data).
1173
    // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore).
1174
    xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
1175
1176
    // Save XML document to writer (semantics is slightly different from xml_node::print, see documentation for details).
1177
    void save(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
1178
1179
  #ifndef PUGIXML_NO_STL
1180
    // Save XML document to stream (semantics is slightly different from xml_node::print, see documentation for details).
1181
    void save(std::basic_ostream<char>& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
1182
    void save(std::basic_ostream<wchar_t>& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const;
1183
  #endif
1184
1185
    // Save XML to file
1186
    bool save_file(const char* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
1187
    bool save_file(const wchar_t* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
1188
1189
    // Get document element
1190
    xml_node document_element() const;
1191
  };
1192
1193
#ifndef PUGIXML_NO_XPATH
1194
  // XPath query return type
1195
  enum xpath_value_type
1196
  {
1197
    xpath_type_none,    // Unknown type (query failed to compile)
1198
    xpath_type_node_set,  // Node set (xpath_node_set)
1199
    xpath_type_number,    // Number
1200
    xpath_type_string,    // String
1201
    xpath_type_boolean    // Boolean
1202
  };
1203
1204
  // XPath parsing result
1205
  struct PUGIXML_CLASS xpath_parse_result
1206
  {
1207
    // Error message (0 if no error)
1208
    const char* error;
1209
1210
    // Last parsed offset (in char_t units from string start)
1211
    ptrdiff_t offset;
1212
1213
    // Default constructor, initializes object to failed state
1214
    xpath_parse_result();
1215
1216
    // Cast to bool operator
1217
    operator bool() const;
1218
1219
    // Get error description
1220
    const char* description() const;
1221
  };
1222
1223
  // A single XPath variable
1224
  class PUGIXML_CLASS xpath_variable
1225
  {
1226
    friend class xpath_variable_set;
1227
1228
  protected:
1229
    xpath_value_type _type;
1230
    xpath_variable* _next;
1231
1232
    xpath_variable(xpath_value_type type);
1233
1234
    // Non-copyable semantics
1235
    xpath_variable(const xpath_variable&);
1236
    xpath_variable& operator=(const xpath_variable&);
1237
1238
  public:
1239
    // Get variable name
1240
    const char_t* name() const;
1241
1242
    // Get variable type
1243
    xpath_value_type type() const;
1244
1245
    // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error
1246
    bool get_boolean() const;
1247
    double get_number() const;
1248
    const char_t* get_string() const;
1249
    const xpath_node_set& get_node_set() const;
1250
1251
    // Set variable value; no type conversion is performed, false is returned on type mismatch error
1252
    bool set(bool value);
1253
    bool set(double value);
1254
    bool set(const char_t* value);
1255
    bool set(const xpath_node_set& value);
1256
  };
1257
1258
  // A set of XPath variables
1259
  class PUGIXML_CLASS xpath_variable_set
1260
  {
1261
  private:
1262
    xpath_variable* _data[64];
1263
1264
    void _assign(const xpath_variable_set& rhs);
1265
    void _swap(xpath_variable_set& rhs);
1266
1267
    xpath_variable* _find(const char_t* name) const;
1268
1269
    static bool _clone(xpath_variable* var, xpath_variable** out_result);
1270
    static void _destroy(xpath_variable* var);
1271
1272
  public:
1273
    // Default constructor/destructor
1274
    xpath_variable_set();
1275
    ~xpath_variable_set();
1276
1277
    // Copy constructor/assignment operator
1278
    xpath_variable_set(const xpath_variable_set& rhs);
1279
    xpath_variable_set& operator=(const xpath_variable_set& rhs);
1280
1281
  #ifdef PUGIXML_HAS_MOVE
1282
    // Move semantics support
1283
    xpath_variable_set(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT;
1284
    xpath_variable_set& operator=(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT;
1285
  #endif
1286
1287
    // Add a new variable or get the existing one, if the types match
1288
    xpath_variable* add(const char_t* name, xpath_value_type type);
1289
1290
    // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch
1291
    bool set(const char_t* name, bool value);
1292
    bool set(const char_t* name, double value);
1293
    bool set(const char_t* name, const char_t* value);
1294
    bool set(const char_t* name, const xpath_node_set& value);
1295
1296
    // Get existing variable by name
1297
    xpath_variable* get(const char_t* name);
1298
    const xpath_variable* get(const char_t* name) const;
1299
  };
1300
1301
  // A compiled XPath query object
1302
  class PUGIXML_CLASS xpath_query
1303
  {
1304
  private:
1305
    void* _impl;
1306
    xpath_parse_result _result;
1307
1308
    typedef void (*unspecified_bool_type)(xpath_query***);
1309
1310
    // Non-copyable semantics
1311
    xpath_query(const xpath_query&);
1312
    xpath_query& operator=(const xpath_query&);
1313
1314
  public:
1315
    // Construct a compiled object from XPath expression.
1316
    // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors.
1317
    explicit xpath_query(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL);
1318
1319
    // Constructor
1320
    xpath_query();
1321
1322
    // Destructor
1323
    ~xpath_query();
1324
1325
  #ifdef PUGIXML_HAS_MOVE
1326
    // Move semantics support
1327
    xpath_query(xpath_query&& rhs) PUGIXML_NOEXCEPT;
1328
    xpath_query& operator=(xpath_query&& rhs) PUGIXML_NOEXCEPT;
1329
  #endif
1330
1331
    // Get query expression return type
1332
    xpath_value_type return_type() const;
1333
1334
    // Evaluate expression as boolean value in the specified context; performs type conversion if necessary.
1335
    // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
1336
    bool evaluate_boolean(const xpath_node& n) const;
1337
1338
    // Evaluate expression as double value in the specified context; performs type conversion if necessary.
1339
    // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
1340
    double evaluate_number(const xpath_node& n) const;
1341
1342
  #ifndef PUGIXML_NO_STL
1343
    // Evaluate expression as string value in the specified context; performs type conversion if necessary.
1344
    // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
1345
    string_t evaluate_string(const xpath_node& n) const;
1346
  #endif
1347
1348
    // Evaluate expression as string value in the specified context; performs type conversion if necessary.
1349
    // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero).
1350
    // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
1351
    // If PUGIXML_NO_EXCEPTIONS is defined, returns empty  set instead.
1352
    size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const;
1353
1354
    // Evaluate expression as node set in the specified context.
1355
    // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors.
1356
    // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead.
1357
    xpath_node_set evaluate_node_set(const xpath_node& n) const;
1358
1359
    // Evaluate expression as node set in the specified context.
1360
    // Return first node in document order, or empty node if node set is empty.
1361
    // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors.
1362
    // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node instead.
1363
    xpath_node evaluate_node(const xpath_node& n) const;
1364
1365
    // Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode)
1366
    const xpath_parse_result& result() const;
1367
1368
    // Safe bool conversion operator
1369
    operator unspecified_bool_type() const;
1370
1371
    // Borland C++ workaround
1372
    bool operator!() const;
1373
  };
1374
1375
  #ifndef PUGIXML_NO_EXCEPTIONS
1376
        #if defined(_MSC_VER)
1377
          // C4275 can be ignored in Visual C++ if you are deriving
1378
          // from a type in the Standard C++ Library
1379
          #pragma warning(push)
1380
          #pragma warning(disable: 4275)
1381
        #endif
1382
  // XPath exception class
1383
  class PUGIXML_CLASS xpath_exception: public std::exception
1384
  {
1385
  private:
1386
    xpath_parse_result _result;
1387
1388
  public:
1389
    // Construct exception from parse result
1390
    explicit xpath_exception(const xpath_parse_result& result);
1391
1392
    // Get error message
1393
    virtual const char* what() const PUGIXML_NOEXCEPT PUGIXML_OVERRIDE;
1394
1395
    // Get parse result
1396
    const xpath_parse_result& result() const;
1397
  };
1398
        #if defined(_MSC_VER)
1399
          #pragma warning(pop)
1400
        #endif
1401
  #endif
1402
1403
  // XPath node class (either xml_node or xml_attribute)
1404
  class PUGIXML_CLASS xpath_node
1405
  {
1406
  private:
1407
    xml_node _node;
1408
    xml_attribute _attribute;
1409
1410
    typedef void (*unspecified_bool_type)(xpath_node***);
1411
1412
  public:
1413
    // Default constructor; constructs empty XPath node
1414
    xpath_node();
1415
1416
    // Construct XPath node from XML node/attribute
1417
    xpath_node(const xml_node& node);
1418
    xpath_node(const xml_attribute& attribute, const xml_node& parent);
1419
1420
    // Get node/attribute, if any
1421
    xml_node node() const;
1422
    xml_attribute attribute() const;
1423
1424
    // Get parent of contained node/attribute
1425
    xml_node parent() const;
1426
1427
    // Safe bool conversion operator
1428
    operator unspecified_bool_type() const;
1429
1430
    // Borland C++ workaround
1431
    bool operator!() const;
1432
1433
    // Comparison operators
1434
    bool operator==(const xpath_node& n) const;
1435
    bool operator!=(const xpath_node& n) const;
1436
  };
1437
1438
#ifdef __BORLANDC__
1439
  // Borland C++ workaround
1440
  bool PUGIXML_FUNCTION operator&&(const xpath_node& lhs, bool rhs);
1441
  bool PUGIXML_FUNCTION operator||(const xpath_node& lhs, bool rhs);
1442
#endif
1443
1444
  // A fixed-size collection of XPath nodes
1445
  class PUGIXML_CLASS xpath_node_set
1446
  {
1447
  public:
1448
    // Collection type
1449
    enum type_t
1450
    {
1451
      type_unsorted,      // Not ordered
1452
      type_sorted,      // Sorted by document order (ascending)
1453
      type_sorted_reverse   // Sorted by document order (descending)
1454
    };
1455
1456
    // Constant iterator type
1457
    typedef const xpath_node* const_iterator;
1458
1459
    // We define non-constant iterator to be the same as constant iterator so that various generic algorithms (i.e. boost foreach) work
1460
    typedef const xpath_node* iterator;
1461
1462
    // Default constructor. Constructs empty set.
1463
    xpath_node_set();
1464
1465
    // Constructs a set from iterator range; data is not checked for duplicates and is not sorted according to provided type, so be careful
1466
    xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted);
1467
1468
    // Destructor
1469
    ~xpath_node_set();
1470
1471
    // Copy constructor/assignment operator
1472
    xpath_node_set(const xpath_node_set& ns);
1473
    xpath_node_set& operator=(const xpath_node_set& ns);
1474
1475
  #ifdef PUGIXML_HAS_MOVE
1476
    // Move semantics support
1477
    xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT;
1478
    xpath_node_set& operator=(xpath_node_set&& rhs) PUGIXML_NOEXCEPT;
1479
  #endif
1480
1481
    // Get collection type
1482
    type_t type() const;
1483
1484
    // Get collection size
1485
    size_t size() const;
1486
1487
    // Indexing operator
1488
    const xpath_node& operator[](size_t index) const;
1489
1490
    // Collection iterators
1491
    const_iterator begin() const;
1492
    const_iterator end() const;
1493
1494
    // Sort the collection in ascending/descending order by document order
1495
    void sort(bool reverse = false);
1496
1497
    // Get first node in the collection by document order
1498
    xpath_node first() const;
1499
1500
    // Check if collection is empty
1501
    bool empty() const;
1502
1503
  private:
1504
    type_t _type;
1505
1506
    xpath_node _storage[1];
1507
1508
    xpath_node* _begin;
1509
    xpath_node* _end;
1510
1511
    void _assign(const_iterator begin, const_iterator end, type_t type);
1512
    void _move(xpath_node_set& rhs) PUGIXML_NOEXCEPT;
1513
  };
1514
#endif
1515
1516
#ifndef PUGIXML_NO_STL
1517
  // Convert wide string to UTF8
1518
  std::basic_string<char> PUGIXML_FUNCTION as_utf8(const wchar_t* str);
1519
  std::basic_string<char> PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t>& str);
1520
1521
  // Convert UTF8 to wide string
1522
  std::basic_string<wchar_t> PUGIXML_FUNCTION as_wide(const char* str);
1523
  std::basic_string<wchar_t> PUGIXML_FUNCTION as_wide(const std::basic_string<char>& str);
1524
#endif
1525
1526
  // Memory allocation function interface; returns pointer to allocated memory or NULL on failure
1527
  typedef void* (*allocation_function)(size_t size);
1528
1529
  // Memory deallocation function interface
1530
  typedef void (*deallocation_function)(void* ptr);
1531
1532
  // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions.
1533
  void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate);
1534
1535
  // Get current memory management functions
1536
  allocation_function PUGIXML_FUNCTION get_memory_allocation_function();
1537
  deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function();
1538
}
1539
1540
#if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC))
1541
namespace std
1542
{
1543
  // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier)
1544
  std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_node_iterator&);
1545
  std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_iterator&);
1546
  std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_named_node_iterator&);
1547
}
1548
#endif
1549
1550
#if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC)
1551
namespace std
1552
{
1553
  // Workarounds for (non-standard) iterator category detection
1554
  std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_node_iterator&);
1555
  std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_iterator&);
1556
  std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_named_node_iterator&);
1557
}
1558
#endif
1559
1560
#endif
1561
1562
// Make sure implementation is included in header-only mode
1563
// Use macro expansion in #include to work around QMake (QTBUG-11923)
1564
#if defined(PUGIXML_HEADER_ONLY) && !defined(PUGIXML_SOURCE)
1565
# define PUGIXML_SOURCE "pugixml.cpp"
1566
# include PUGIXML_SOURCE
1567
#endif
1568
1569
/**
1570
 * Copyright (c) 2006-2026 Arseny Kapoulkine
1571
 *
1572
 * Permission is hereby granted, free of charge, to any person
1573
 * obtaining a copy of this software and associated documentation
1574
 * files (the "Software"), to deal in the Software without
1575
 * restriction, including without limitation the rights to use,
1576
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
1577
 * copies of the Software, and to permit persons to whom the
1578
 * Software is furnished to do so, subject to the following
1579
 * conditions:
1580
 *
1581
 * The above copyright notice and this permission notice shall be
1582
 * included in all copies or substantial portions of the Software.
1583
 *
1584
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1585
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1586
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1587
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1588
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1589
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1590
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1591
 * OTHER DEALINGS IN THE SOFTWARE.
1592
 */