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