diff --git a/docs/manual.adoc b/docs/manual.adoc index 1f80929..ac51535 100644 --- a/docs/manual.adoc +++ b/docs/manual.adoc @@ -46,7 +46,7 @@ Thanks to *Vyacheslav Egorov* for documentation proofreading and fuzz testing. The pugixml library is distributed under the MIT license: .... -Copyright (c) 2006-2020 Arseny Kapoulkine +Copyright (c) 2006-2022 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -74,7 +74,7 @@ This means that you can freely use pugixml in your applications, both open-sourc .... This software is based on pugixml library (https://pugixml.org). -pugixml is Copyright (C) 2006-2020 Arseny Kapoulkine. +pugixml is Copyright (C) 2006-2022 Arseny Kapoulkine. .... [[install]] @@ -1604,12 +1604,12 @@ bool xml_document::save_file(const char* path, const char_t* indent = "\t", unsi bool xml_document::save_file(const wchar_t* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; ---- -These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see <>) and output data encoding (see <>). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc. +These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see <>) and output data encoding (see <>). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc. The functions return `true` on success and `false` if the file could not be opened or written to. File path is passed to the system file opening function as is in case of the first function (which accepts `const char* path`); the second function either uses a special file opening function if it is provided by the runtime library or converts the path to UTF-8 and uses the system file opening function. [[xml_writer_file]] -`save_file` opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. If the file could not be opened, the function returns `false`. Calling `save_file` is equivalent to creating an `xml_writer_file` object with `FILE*` handle as the only constructor argument and then calling `save`; see <> for writer interface details. +`save_file` opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. Calling `save_file` is equivalent to creating an `xml_writer_file` object with `FILE*` handle as the only constructor argument and then calling `save`; see <> for writer interface details. This is a simple example of saving XML document to file (link:samples/save_file.cpp[]): @@ -2138,6 +2138,27 @@ Because of the differences in document object models, performance considerations :!numbered: +[[v1.12]] +=== v1.12 ^2022-02-09^ + +Maintenance release. Changes: + +* Bug fixes: + . Fix a bug in xml_document move construction when the source of the move is empty + . Fix const-correctness issues with iterator objects to support C++20 ranges + +* XPath improvements: + . Improved detection of overly complex queries that may result in stack overflow during parsing + +* Compatibility improvements: + . Fix Cygwin support for DLL builds + . Fix Windows CE support + . Add NuGet builds and project files for VS2022 + +* Build system changes + . All CMake options now have the prefix `PUGIXML_`. This may require changing dependent build configurations. + . Many build settings are now exposed via CMake settings, most notably `PUGIXML_COMPACT` and `PUGIXML_WCHAR_MODE` can be set without changing `pugiconfig.hpp` + [[v1.11]] === v1.11 ^2020-11-26^ @@ -2156,6 +2177,9 @@ Maintenance release. Changes: . Fix Wzero-as-null-pointer-constant warnings in pugixml.hpp . Work around several static analysis false positives +* Build system changes + . The CMake package for pugixml now provides a `pugixml::pugixml` target rather than a `pugixml` target. A compatibility `pugixml` target is provided if at least version 1.11 is not requested. + [[v1.10]] === v1.10 ^2019-09-15^ diff --git a/docs/manual.html b/docs/manual.html index 35acf77..6457a9a 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -4,26 +4,24 @@ - + -pugixml 1.11 manual +pugixml 1.12 manual + @@ -686,9 +758,9 @@ pugixml is Copyright (C) 2006-2020 Arseny Kapoulkine.

You can download the latest source distribution as an archive:

-

pugixml-1.11.zip (Windows line endings) +

pugixml-1.12.zip (Windows line endings) / -pugixml-1.11.tar.gz (Unix line endings)

+pugixml-1.12.tar.gz (Unix line endings)

The distribution contains library source, documentation (the manual you’re reading now and the quick start guide) and some code examples. After downloading the distribution, install pugixml by extracting all files from the compressed archive.

@@ -709,7 +781,7 @@ pugixml is Copyright (C) 2006-2020 Arseny Kapoulkine.
git clone https://github.com/zeux/pugixml
 cd pugixml
-git checkout v1.11
+git checkout v1.12
@@ -726,7 +798,7 @@ git checkout v1.11
-
svn checkout https://github.com/zeux/pugixml/tags/v1.11 pugixml
+
svn checkout https://github.com/zeux/pugixml/tags/v1.12 pugixml
@@ -774,7 +846,7 @@ git checkout v1.11
-
pugixml.cpp(3477) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?
+
pugixml.cpp(3477) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?
@@ -871,9 +943,9 @@ git checkout v1.11
#ifdef _DLL
-    #define PUGIXML_API __declspec(dllexport)
+    #define PUGIXML_API __declspec(dllexport)
 #else
-    #define PUGIXML_API __declspec(dllimport)
+    #define PUGIXML_API __declspec(dllimport)
 #endif
@@ -908,7 +980,7 @@ can include pugixml.cpp in your project (see B
#ifndef _DEBUG
-    #define PUGIXML_HEADER_ONLY
+    #define PUGIXML_HEADER_ONLY
 #endif
@@ -999,7 +1071,7 @@ In that example PUGIXML_API is inconsistent between several source

Element/tag node (node_element) - this is the most common type of node, which represents XML elements. Element nodes have a name, a collection of attributes and a collection of child nodes (both of which may be empty). The attribute is a simple name/value pair. The example XML representation of element nodes is as follows:

-
<node attr="value"><child/></node>
+
<node attr="value"><child/></node>
@@ -1010,7 +1082,7 @@ In that example PUGIXML_API is inconsistent between several source

Plain character data nodes (node_pcdata) represent plain text in XML. PCDATA nodes have a value, but do not have a name or children/attributes. Note that plain character data is not a part of the element node but instead has its own node; an element node can have several child PCDATA nodes. The example XML representation of text nodes is as follows:

-
<node> text1 <child/> text2 </node>
+
<node> text1 <child/> text2 </node>
@@ -1021,7 +1093,7 @@ In that example PUGIXML_API is inconsistent between several source

Character data nodes (node_cdata) represent text in XML that is quoted in a special way. CDATA nodes do not differ from PCDATA nodes except in XML representation - the above text example looks like this with CDATA:

-
<node> <![CDATA[text1]]> <child/> <![CDATA[text2]]> </node>
+
<node> <![CDATA[text1]]> <child/> <![CDATA[text2]]> </node>
@@ -1032,7 +1104,7 @@ In that example PUGIXML_API is inconsistent between several source

Comment nodes (node_comment) represent comments in XML. Comment nodes have a value, but do not have a name or children/attributes. The example XML representation of a comment node is as follows:

-
<!-- comment text -->
+
<!-- comment text -->
@@ -1043,7 +1115,7 @@ In that example PUGIXML_API is inconsistent between several source

Processing instruction node (node_pi) represent processing instructions (PI) in XML. PI nodes have a name and an optional value, but do not have children/attributes. The example XML representation of a PI node is as follows:

-
<?name value?>
+
<?name value?>
@@ -1054,7 +1126,7 @@ In that example PUGIXML_API is inconsistent between several source

Declaration node (node_declaration) represents document declarations in XML. Declaration nodes have a name ("xml") and an optional collection of attributes, but do not have value or children. There can be only one declaration node in a document; moreover, it should be the topmost node (its parent should be the document). The example XML representation of a declaration node is as follows:

-
<?xml version="1.0"?>
+
<?xml version="1.0"?>
@@ -1065,7 +1137,7 @@ In that example PUGIXML_API is inconsistent between several source

Document type declaration node (node_doctype) represents document type declarations in XML. Document type declaration nodes have a value, which corresponds to the entire document type contents; no additional nodes are created for inner elements like <!ENTITY>. There can be only one document type declaration node in a document; moreover, it should be the topmost node (its parent should be the document). The example XML representation of a document type declaration node is as follows:

-
<!DOCTYPE greeting [ <!ELEMENT greeting (#PCDATA)> ]>
+
<!DOCTYPE greeting [ <!ELEMENT greeting (#PCDATA)> ]>
@@ -1174,8 +1246,8 @@ Finally handles can be implicitly cast to boolean-like objects, so that you can
-
bool xml_attribute::empty() const;
-bool xml_node::empty() const;
+
bool xml_attribute::empty() const;
+bool xml_node::empty() const;
@@ -1204,8 +1276,8 @@ If the size of wchar_t is 2, pugixml assumes UTF-16 encoding instea
-
const char* xml_node::name() const;
-bool xml_node::set_name(const char* value);
+
const char* xml_node::name() const;
+bool xml_node::set_name(const char* value);
@@ -1213,8 +1285,8 @@ If the size of wchar_t is 2, pugixml assumes UTF-16 encoding instea
-
const wchar_t* xml_node::name() const;
-bool xml_node::set_name(const wchar_t* value);
+
const wchar_t* xml_node::name() const;
+bool xml_node::set_name(const wchar_t* value);
@@ -1230,8 +1302,8 @@ There are cases when you’ll have to convert string data between UTF-8 and
-
std::string as_utf8(const wchar_t* str);
-std::wstring as_wide(const char* str);
+
std::string as_utf8(const wchar_t* str);
+std::wstring as_wide(const char* str);
@@ -1239,8 +1311,8 @@ There are cases when you’ll have to convert string data between UTF-8 and
-
std::string as_utf8(const std::wstring& str);
-std::wstring as_wide(const std::string& str);
+
std::string as_utf8(const std::wstring& str);
+std::wstring as_wide(const std::string& str);
@@ -1317,8 +1389,8 @@ All memory for tree structure, tree data and XPath objects is allocated via glob
-
typedef void* (*allocation_function)(size_t size);
-typedef void (*deallocation_function)(void* ptr);
+
typedef void* (*allocation_function)(size_t size);
+typedef void (*deallocation_function)(void* ptr);
@@ -1327,9 +1399,9 @@ You can use the following accessor functions to change or get current memory man
-
void set_memory_management_functions(allocation_function allocate, deallocation_function deallocate);
-allocation_function get_memory_allocation_function();
-deallocation_function get_memory_deallocation_function();
+
void set_memory_management_functions(allocation_function allocate, deallocation_function deallocate);
+allocation_function get_memory_allocation_function();
+deallocation_function get_memory_deallocation_function();
@@ -1343,20 +1415,20 @@ You can use the following accessor functions to change or get current memory man
-
void* custom_allocate(size_t size)
-{
-    return new (std::nothrow) char[size];
-}
+
void* custom_allocate(size_t size)
+{
+    return new (std::nothrow) char[size];
+}
 
-void custom_deallocate(void* ptr)
-{
-    delete[] static_cast<char*>(ptr);
-}
+void custom_deallocate(void* ptr) +{ + delete[] static_cast<char*>(ptr); +}
-
pugi::set_memory_management_functions(custom_allocate, custom_deallocate);
+
pugi::set_memory_management_functions(custom_allocate, custom_deallocate);
@@ -1432,8 +1504,8 @@ The most common source of XML data is files; pugixml provides dedicated function
-
xml_parse_result xml_document::load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
-xml_parse_result xml_document::load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+
xml_parse_result xml_document::load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+xml_parse_result xml_document::load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
@@ -1450,11 +1522,11 @@ The most common source of XML data is files; pugixml provides dedicated function
-
pugi::xml_document doc;
+
pugi::xml_document doc;
 
-pugi::xml_parse_result result = doc.load_file("tree.xml");
+pugi::xml_parse_result result = doc.load_file("tree.xml");
 
-std::cout << "Load result: " << result.description() << ", mesh name: " << doc.child("mesh").attribute("name").value() << std::endl;
+std::cout << "Load result: " << result.description() << ", mesh name: " << doc.child("mesh").attribute("name").value() << std::endl;
@@ -1466,9 +1538,9 @@ Sometimes XML data should be loaded from some other source than a file, i.e. HTT
-
xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
-xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
-xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+
xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
@@ -1485,7 +1557,7 @@ Sometimes XML data should be loaded from some other source than a file, i.e. HTT
-
xml_parse_result xml_document::load_string(const char_t* contents, unsigned int options = parse_default);
+
xml_parse_result xml_document::load_string(const char_t* contents, unsigned int options = parse_default);
@@ -1496,44 +1568,44 @@ Sometimes XML data should be loaded from some other source than a file, i.e. HTT
-
const char source[] = "<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>";
-size_t size = sizeof(source);
+
const char source[] = "<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>";
+size_t size = sizeof(source);
// You can use load_buffer to load document from immutable memory block:
-pugi::xml_parse_result result = doc.load_buffer(source, size);
+pugi::xml_parse_result result = doc.load_buffer(source, size);
// You can use load_buffer_inplace to load document from mutable memory block; the block's lifetime must exceed that of document
-char* buffer = new char[size];
-memcpy(buffer, source, size);
+char* buffer = new char[size];
+memcpy(buffer, source, size);
 
 // The block can be allocated by any method; the block is modified during parsing
-pugi::xml_parse_result result = doc.load_buffer_inplace(buffer, size);
+pugi::xml_parse_result result = doc.load_buffer_inplace(buffer, size);
 
 // You have to destroy the block yourself after the document is no longer used
-delete[] buffer;
+delete[] buffer;
// You can use load_buffer_inplace_own to load document from mutable memory block and to pass the ownership of this block
 // The block has to be allocated via pugixml allocation function - using i.e. operator new here is incorrect
-char* buffer = static_cast<char*>(pugi::get_memory_allocation_function()(size));
-memcpy(buffer, source, size);
+char* buffer = static_cast<char*>(pugi::get_memory_allocation_function()(size));
+memcpy(buffer, source, size);
 
 // The block will be deleted by the document
-pugi::xml_parse_result result = doc.load_buffer_inplace_own(buffer, size);
+pugi::xml_parse_result result = doc.load_buffer_inplace_own(buffer, size);
// You can use load to load document from null-terminated strings, for example literals:
-pugi::xml_parse_result result = doc.load_string("<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>");
+pugi::xml_parse_result result = doc.load_string("<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>");
@@ -1544,8 +1616,8 @@ Sometimes XML data should be loaded from some other source than a file, i.e. HTT
-
xml_parse_result xml_document::load(std::istream& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
-xml_parse_result xml_document::load(std::wistream& stream, unsigned int options = parse_default);
+
xml_parse_result xml_document::load(std::istream& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+xml_parse_result xml_document::load(std::wistream& stream, unsigned int options = parse_default);
@@ -1559,8 +1631,8 @@ Sometimes XML data should be loaded from some other source than a file, i.e. HTT
-
std::ifstream stream("weekly-utf-8.xml");
-pugi::xml_parse_result result = doc.load(stream);
+
std::ifstream stream("weekly-utf-8.xml");
+pugi::xml_parse_result result = doc.load(stream);
@@ -1571,15 +1643,15 @@ Sometimes XML data should be loaded from some other source than a file, i.e. HTT
-
struct xml_parse_result
-{
-    xml_parse_status status;
-    ptrdiff_t offset;
-    xml_encoding encoding;
+
struct xml_parse_result
+{
+    xml_parse_status status;
+    ptrdiff_t offset;
+    xml_encoding encoding;
 
-    operator bool() const;
-    const char* description() const;
-};
+ operator bool() const; + const char* description() const; +};
@@ -1661,19 +1733,19 @@ Offset is calculated in the XML buffer in native encoding; if encoding conversio
-
pugi::xml_document doc;
-pugi::xml_parse_result result = doc.load_string(source);
+
pugi::xml_document doc;
+pugi::xml_parse_result result = doc.load_string(source);
 
-if (result)
-{
-    std::cout << "XML [" << source << "] parsed without errors, attr value: [" << doc.child("node").attribute("attr").value() << "]\n\n";
-}
-else
-{
-    std::cout << "XML [" << source << "] parsed with errors, attr value: [" << doc.child("node").attribute("attr").value() << "]\n";
-    std::cout << "Error description: " << result.description() << "\n";
-    std::cout << "Error offset: " << result.offset << " (error at [..." << (source + result.offset) << "]\n\n";
-}
+if (result) +{ + std::cout << "XML [" << source << "] parsed without errors, attr value: [" << doc.child("node").attribute("attr").value() << "]\n\n"; +} +else +{ + std::cout << "XML [" << source << "] parsed with errors, attr value: [" << doc.child("node").attribute("attr").value() << "]\n"; + std::cout << "Error description: " << result.description() << "\n"; + std::cout << "Error offset: " << result.offset << " (error at [..." << (source + result.offset) << "]\n\n"; +}
@@ -1796,23 +1868,23 @@ Using in-place parsing (load_buffer
-
const char* source = "<!--comment--><node>&lt;</node>";
+
const char* source = "<!--comment--><node>&lt;</node>";
 
 // Parsing with default options; note that comment node is not added to the tree, and entity reference &lt; is expanded
-doc.load_string(source);
-std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n";
+doc.load_string(source);
+std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n";
 
 // Parsing with additional parse_comments option; comment node is now added to the tree
-doc.load_string(source, pugi::parse_default | pugi::parse_comments);
-std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n";
+doc.load_string(source, pugi::parse_default | pugi::parse_comments);
+std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n";
 
 // Parsing with additional parse_comments option and without the (default) parse_escapes option; &lt; is not expanded
-doc.load_string(source, (pugi::parse_default | pugi::parse_comments) & ~pugi::parse_escapes);
-std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n";
+doc.load_string(source, (pugi::parse_default | pugi::parse_comments) & ~pugi::parse_escapes);
+std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n";
 
 // Parsing with minimal option mask; comment node is not added to the tree, and &lt; is not expanded
-doc.load_string(source, pugi::parse_minimal);
-std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n";
+doc.load_string(source, pugi::parse_minimal); +std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n";
@@ -1930,16 +2002,16 @@ The internal representation of the document is a tree, where each node has a lis
-
xml_node xml_node::parent() const;
-xml_node xml_node::first_child() const;
-xml_node xml_node::last_child() const;
-xml_node xml_node::next_sibling() const;
-xml_node xml_node::previous_sibling() const;
+
xml_node xml_node::parent() const;
+xml_node xml_node::first_child() const;
+xml_node xml_node::last_child() const;
+xml_node xml_node::next_sibling() const;
+xml_node xml_node::previous_sibling() const;
 
-xml_attribute xml_node::first_attribute() const;
-xml_attribute xml_node::last_attribute() const;
-xml_attribute xml_attribute::next_attribute() const;
-xml_attribute xml_attribute::previous_attribute() const;
+xml_attribute xml_node::first_attribute() const; +xml_attribute xml_node::last_attribute() const; +xml_attribute xml_attribute::next_attribute() const; +xml_attribute xml_attribute::previous_attribute() const;
@@ -1965,17 +2037,17 @@ Because of memory consumption reasons, attributes do not have a link to their pa
-
for (pugi::xml_node tool = tools.first_child(); tool; tool = tool.next_sibling())
-{
-    std::cout << "Tool:";
+
for (pugi::xml_node tool = tools.first_child(); tool; tool = tool.next_sibling())
+{
+    std::cout << "Tool:";
 
-    for (pugi::xml_attribute attr = tool.first_attribute(); attr; attr = attr.next_attribute())
-    {
-        std::cout << " " << attr.name() << "=" << attr.value();
-    }
+    for (pugi::xml_attribute attr = tool.first_attribute(); attr; attr = attr.next_attribute())
+    {
+        std::cout << " " << attr.name() << "=" << attr.value();
+    }
 
-    std::cout << std::endl;
-}
+ std::cout << std::endl; +}
@@ -1987,8 +2059,8 @@ Apart from structural information (parent, child nodes, attributes), nodes can h
-
const char_t* xml_node::name() const;
-const char_t* xml_node::value() const;
+
const char_t* xml_node::name() const;
+const char_t* xml_node::value() const;
@@ -1999,9 +2071,9 @@ Apart from structural information (parent, child nodes, attributes), nodes can h
-
const char_t* xml_node::child_value() const;
-const char_t* xml_node::child_value(const char_t* name) const;
-xml_text xml_node::text() const;
+
const char_t* xml_node::child_value() const;
+const char_t* xml_node::child_value(const char_t* name) const;
+xml_text xml_node::text() const;
@@ -2022,8 +2094,8 @@ All attributes have name and value, both of which are strings (value may be empt
-
const char_t* xml_attribute::name() const;
-const char_t* xml_attribute::value() const;
+
const char_t* xml_attribute::name() const;
+const char_t* xml_attribute::value() const;
@@ -2034,7 +2106,7 @@ All attributes have name and value, both of which are strings (value may be empt
-
const char_t* xml_attribute::as_string(const char_t* def = "") const;
+
const char_t* xml_attribute::as_string(const char_t* def = "") const;
@@ -2046,13 +2118,13 @@ In many cases attribute values have types that are not strings - i.e. an attribu
-
int xml_attribute::as_int(int def = 0) const;
-unsigned int xml_attribute::as_uint(unsigned int def = 0) const;
-double xml_attribute::as_double(double def = 0) const;
-float xml_attribute::as_float(float def = 0) const;
-bool xml_attribute::as_bool(bool def = false) const;
-long long xml_attribute::as_llong(long long def = 0) const;
-unsigned long long xml_attribute::as_ullong(unsigned long long def = 0) const;
+
int xml_attribute::as_int(int def = 0) const;
+unsigned int xml_attribute::as_uint(unsigned int def = 0) const;
+double xml_attribute::as_double(double def = 0) const;
+float xml_attribute::as_float(float def = 0) const;
+bool xml_attribute::as_bool(bool def = false) const;
+long long xml_attribute::as_llong(long long def = 0) const;
+unsigned long long xml_attribute::as_ullong(unsigned long long def = 0) const;
@@ -2093,13 +2165,13 @@ Number conversion functions depend on current C locale as set with setloca
-
for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
-{
-    std::cout << "Tool " << tool.attribute("Filename").value();
-    std::cout << ": AllowRemote " << tool.attribute("AllowRemote").as_bool();
-    std::cout << ", Timeout " << tool.attribute("Timeout").as_int();
-    std::cout << ", Description '" << tool.child_value("Description") << "'\n";
-}
+
for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
+{
+    std::cout << "Tool " << tool.attribute("Filename").value();
+    std::cout << ": AllowRemote " << tool.attribute("AllowRemote").as_bool();
+    std::cout << ", Timeout " << tool.attribute("Timeout").as_int();
+    std::cout << ", Description '" << tool.child_value("Description") << "'\n";
+}
@@ -2111,10 +2183,10 @@ Since a lot of document traversal consists of finding the node/attribute with th
-
xml_node xml_node::child(const char_t* name) const;
-xml_attribute xml_node::attribute(const char_t* name) const;
-xml_node xml_node::next_sibling(const char_t* name) const;
-xml_node xml_node::previous_sibling(const char_t* name) const;
+
xml_node xml_node::child(const char_t* name) const;
+xml_attribute xml_node::attribute(const char_t* name) const;
+xml_node xml_node::next_sibling(const char_t* name) const;
+xml_node xml_node::previous_sibling(const char_t* name) const;
@@ -2125,7 +2197,7 @@ Since a lot of document traversal consists of finding the node/attribute with th
-
for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
+
for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
@@ -2133,8 +2205,8 @@ Since a lot of document traversal consists of finding the node/attribute with th
-
xml_node xml_node::find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
-xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const;
+
xml_node xml_node::find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
+xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const;
@@ -2148,12 +2220,12 @@ Since a lot of document traversal consists of finding the node/attribute with th
-
std::cout << "Tool for *.dae generation: " << tools.find_child_by_attribute("Tool", "OutputFileMasks", "*.dae").attribute("Filename").value() << "\n";
+
std::cout << "Tool for *.dae generation: " << tools.find_child_by_attribute("Tool", "OutputFileMasks", "*.dae").attribute("Filename").value() << "\n";
 
-for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
-{
-    std::cout << "Tool " << tool.attribute("Filename").value() << "\n";
-}
+for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool")) +{ + std::cout << "Tool " << tool.attribute("Filename").value() << "\n"; +}
@@ -2165,9 +2237,9 @@ If your C++ compiler supports range-based for-loop (this is a C++
-
implementation-defined-type xml_node::children() const;
-implementation-defined-type xml_node::children(const char_t* name) const;
-implementation-defined-type xml_node::attributes() const;
+
implementation-defined-type xml_node::children() const;
+implementation-defined-type xml_node::children(const char_t* name) const;
+implementation-defined-type xml_node::attributes() const;
@@ -2178,22 +2250,22 @@ If your C++ compiler supports range-based for-loop (this is a C++
-
for (pugi::xml_node tool: tools.children("Tool"))
-{
-    std::cout << "Tool:";
+
for (pugi::xml_node tool: tools.children("Tool"))
+{
+    std::cout << "Tool:";
 
-    for (pugi::xml_attribute attr: tool.attributes())
-    {
-        std::cout << " " << attr.name() << "=" << attr.value();
-    }
+    for (pugi::xml_attribute attr: tool.attributes())
+    {
+        std::cout << " " << attr.name() << "=" << attr.value();
+    }
 
-    for (pugi::xml_node child: tool.children())
-    {
-        std::cout << ", child " << child.name();
-    }
+    for (pugi::xml_node child: tool.children())
+    {
+        std::cout << ", child " << child.name();
+    }
 
-    std::cout << std::endl;
-}
+ std::cout << std::endl; +}
@@ -2201,7 +2273,7 @@ If your C++ compiler supports range-based for-loop (this is a C++
-
for (pugi::xml_node child: tool)
+
for (pugi::xml_node child: tool)
@@ -2213,16 +2285,16 @@ Child node lists and attribute lists are simply double-linked lists; while you c
-
class xml_node_iterator;
-class xml_attribute_iterator;
+
class xml_node_iterator;
+class xml_attribute_iterator;
 
-typedef xml_node_iterator xml_node::iterator;
-iterator xml_node::begin() const;
-iterator xml_node::end() const;
+typedef xml_node_iterator xml_node::iterator;
+iterator xml_node::begin() const;
+iterator xml_node::end() const;
 
-typedef xml_attribute_iterator xml_node::attribute_iterator;
-attribute_iterator xml_node::attributes_begin() const;
-attribute_iterator xml_node::attributes_end() const;
+typedef xml_attribute_iterator xml_node::attribute_iterator; +attribute_iterator xml_node::attributes_begin() const; +attribute_iterator xml_node::attributes_end() const;
@@ -2239,17 +2311,17 @@ Child node lists and attribute lists are simply double-linked lists; while you c
-
for (pugi::xml_node_iterator it = tools.begin(); it != tools.end(); ++it)
-{
-    std::cout << "Tool:";
+
for (pugi::xml_node_iterator it = tools.begin(); it != tools.end(); ++it)
+{
+    std::cout << "Tool:";
 
-    for (pugi::xml_attribute_iterator ait = it->attributes_begin(); ait != it->attributes_end(); ++ait)
-    {
-        std::cout << " " << ait->name() << "=" << ait->value();
-    }
+    for (pugi::xml_attribute_iterator ait = it->attributes_begin(); ait != it->attributes_end(); ++ait)
+    {
+        std::cout << " " << ait->name() << "=" << ait->value();
+    }
 
-    std::cout << std::endl;
-}
+ std::cout << std::endl; +}
@@ -2272,17 +2344,17 @@ Node and attribute iterators are somewhere in the middle between const and non-c
-
class xml_tree_walker
-{
-public:
-    virtual bool begin(xml_node& node);
-    virtual bool for_each(xml_node& node) = 0;
-    virtual bool end(xml_node& node);
+
class xml_tree_walker
+{
+public:
+    virtual bool begin(xml_node& node);
+    virtual bool for_each(xml_node& node) = 0;
+    virtual bool end(xml_node& node);
 
-    int depth() const;
-};
+    int depth() const;
+};
 
-bool xml_node::traverse(xml_tree_walker& walker);
+bool xml_node::traverse(xml_tree_walker& walker);
@@ -2313,23 +2385,23 @@ The traversal is launched by calling traverse function on traversal
-
struct simple_walker: pugi::xml_tree_walker
-{
-    virtual bool for_each(pugi::xml_node& node)
-    {
-        for (int i = 0; i < depth(); ++i) std::cout << "  "; // indentation
+
struct simple_walker: pugi::xml_tree_walker
+{
+    virtual bool for_each(pugi::xml_node& node)
+    {
+        for (int i = 0; i < depth(); ++i) std::cout << "  "; // indentation
 
-        std::cout << node_types[node.type()] << ": name='" << node.name() << "', value='" << node.value() << "'\n";
+        std::cout << node_types[node.type()] << ": name='" << node.name() << "', value='" << node.value() << "'\n";
 
-        return true; // continue traversal
-    }
-};
+ return true; // continue traversal + } +};
-
simple_walker walker;
-doc.traverse(walker);
+
simple_walker walker;
+doc.traverse(walker);
@@ -2341,9 +2413,9 @@ While there are existing functions for getting a node/attribute with known conte
-
template <typename Predicate> xml_attribute xml_node::find_attribute(Predicate pred) const;
-template <typename Predicate> xml_node xml_node::find_child(Predicate pred) const;
-template <typename Predicate> xml_node xml_node::find_node(Predicate pred) const;
+
template <typename Predicate> xml_attribute xml_node::find_attribute(Predicate pred) const;
+template <typename Predicate> xml_node xml_node::find_child(Predicate pred) const;
+template <typename Predicate> xml_node xml_node::find_node(Predicate pred) const;
@@ -2363,38 +2435,38 @@ While there are existing functions for getting a node/attribute with known conte
-
bool small_timeout(pugi::xml_node node)
-{
-    return node.attribute("Timeout").as_int() < 20;
-}
+
bool small_timeout(pugi::xml_node node)
+{
+    return node.attribute("Timeout").as_int() < 20;
+}
 
-struct allow_remote_predicate
-{
-    bool operator()(pugi::xml_attribute attr) const
-    {
-        return strcmp(attr.name(), "AllowRemote") == 0;
-    }
+struct allow_remote_predicate
+{
+    bool operator()(pugi::xml_attribute attr) const
+    {
+        return strcmp(attr.name(), "AllowRemote") == 0;
+    }
 
-    bool operator()(pugi::xml_node node) const
-    {
-        return node.attribute("AllowRemote").as_bool();
-    }
-};
+ bool operator()(pugi::xml_node node) const + { + return node.attribute("AllowRemote").as_bool(); + } +};
// Find child via predicate (looks for direct children only)
-std::cout << tools.find_child(allow_remote_predicate()).attribute("Filename").value() << std::endl;
+std::cout << tools.find_child(allow_remote_predicate()).attribute("Filename").value() << std::endl;
 
 // Find node via predicate (looks for all descendants in depth-first order)
-std::cout << doc.find_node(allow_remote_predicate()).attribute("Filename").value() << std::endl;
+std::cout << doc.find_node(allow_remote_predicate()).attribute("Filename").value() << std::endl;
 
 // Find attribute via predicate
-std::cout << tools.last_child().find_attribute(allow_remote_predicate()).value() << std::endl;
+std::cout << tools.last_child().find_attribute(allow_remote_predicate()).value() << std::endl;
 
 // We can use simple functions instead of function objects
-std::cout << tools.find_child(small_timeout).attribute("Filename").value() << std::endl;
+std::cout << tools.find_child(small_timeout).attribute("Filename").value() << std::endl;
@@ -2408,7 +2480,7 @@ While there are existing functions for getting a node/attribute with known conte
-
xml_text xml_node::text() const;
+
xml_text xml_node::text() const;
@@ -2420,7 +2492,7 @@ You can check if the text object is bound to a valid PCDATA/CDATA node by using
-
bool xml_text::empty() const;
+
bool xml_text::empty() const;
@@ -2428,7 +2500,7 @@ You can check if the text object is bound to a valid PCDATA/CDATA node by using
-
const char_t* xml_text::get() const;
+
const char_t* xml_text::get() const;
@@ -2440,14 +2512,14 @@ If you need a non-empty string if the text object is empty, or if the text conte
-
const char_t* xml_text::as_string(const char_t* def = "") const;
-int xml_text::as_int(int def = 0) const;
-unsigned int xml_text::as_uint(unsigned int def = 0) const;
-double xml_text::as_double(double def = 0) const;
-float xml_text::as_float(float def = 0) const;
-bool xml_text::as_bool(bool def = false) const;
-long long xml_text::as_llong(long long def = 0) const;
-unsigned long long xml_text::as_ullong(unsigned long long def = 0) const;
+
const char_t* xml_text::as_string(const char_t* def = "") const;
+int xml_text::as_int(int def = 0) const;
+unsigned int xml_text::as_uint(unsigned int def = 0) const;
+double xml_text::as_double(double def = 0) const;
+float xml_text::as_float(float def = 0) const;
+bool xml_text::as_bool(bool def = false) const;
+long long xml_text::as_llong(long long def = 0) const;
+unsigned long long xml_text::as_ullong(unsigned long long def = 0) const;
@@ -2458,7 +2530,7 @@ If you need a non-empty string if the text object is empty, or if the text conte
-
xml_node xml_text::data() const;
+
xml_node xml_text::data() const;
@@ -2469,10 +2541,10 @@ If you need a non-empty string if the text object is empty, or if the text conte
-
std::cout << "Project name: " << project.child("name").text().get() << std::endl;
-std::cout << "Project version: " << project.child("version").text().as_double() << std::endl;
-std::cout << "Project visibility: " << (project.child("public").text().as_bool(/* def= */ true) ? "public" : "private") << std::endl;
-std::cout << "Project description: " << project.child("description").text().get() << std::endl;
+
std::cout << "Project name: " << project.child("name").text().get() << std::endl;
+std::cout << "Project version: " << project.child("version").text().as_double() << std::endl;
+std::cout << "Project visibility: " << (project.child("public").text().as_bool(/* def= */ true) ? "public" : "private") << std::endl;
+std::cout << "Project description: " << project.child("description").text().get() << std::endl;
@@ -2483,7 +2555,7 @@ If you need a non-empty string if the text object is empty, or if the text conte
-
xml_node xml_node::root() const;
+
xml_node xml_node::root() const;
@@ -2495,8 +2567,8 @@ While pugixml supports complex XPath expressions, sometimes a simple path handli
-
string_t xml_node::path(char_t delimiter = '/') const;
-xml_node xml_node::first_element_by_path(const char_t* path, char_t delimiter = '/') const;
+
string_t xml_node::path(char_t delimiter = '/') const;
+xml_node xml_node::first_element_by_path(const char_t* path, char_t delimiter = '/') const;
@@ -2522,7 +2594,7 @@ While pugixml supports complex XPath expressions, sometimes a simple path handli
-
ptrdiff_t xml_node::offset_debug() const;
+
ptrdiff_t xml_node::offset_debug() const;
@@ -2548,8 +2620,8 @@ As discussed before, nodes can have name and value, both of which are strings. D
-
bool xml_node::set_name(const char_t* rhs);
-bool xml_node::set_value(const char_t* rhs);
+
bool xml_node::set_name(const char_t* rhs);
+bool xml_node::set_value(const char_t* rhs);
@@ -2560,18 +2632,18 @@ As discussed before, nodes can have name and value, both of which are strings. D
-
pugi::xml_node node = doc.child("node");
+
pugi::xml_node node = doc.child("node");
 
 // change node name
-std::cout << node.set_name("notnode");
-std::cout << ", new node name: " << node.name() << std::endl;
+std::cout << node.set_name("notnode");
+std::cout << ", new node name: " << node.name() << std::endl;
 
 // change comment text
-std::cout << doc.last_child().set_value("useless comment");
-std::cout << ", new comment text: " << doc.last_child().value() << std::endl;
+std::cout << doc.last_child().set_value("useless comment");
+std::cout << ", new comment text: " << doc.last_child().value() << std::endl;
 
 // we can't change value of the element or name of the comment
-std::cout << node.set_value("1") << ", " << doc.last_child().set_name("2") << std::endl;
+std::cout << node.set_value("1") << ", " << doc.last_child().set_name("2") << std::endl;
@@ -2583,8 +2655,8 @@ All attributes have name and value, both of which are strings (value may be empt
-
bool xml_attribute::set_name(const char_t* rhs);
-bool xml_attribute::set_value(const char_t* rhs);
+
bool xml_attribute::set_name(const char_t* rhs);
+bool xml_attribute::set_value(const char_t* rhs);
@@ -2595,17 +2667,17 @@ All attributes have name and value, both of which are strings (value may be empt
-
bool xml_attribute::set_value(int rhs);
-bool xml_attribute::set_value(unsigned int rhs);
-bool xml_attribute::set_value(long rhs);
-bool xml_attribute::set_value(unsigned long rhs);
-bool xml_attribute::set_value(double rhs);
-bool xml_attribute::set_value(double rhs, int precision);
-bool xml_attribute::set_value(float rhs);
-bool xml_attribute::set_value(float rhs, int precision);
-bool xml_attribute::set_value(bool rhs);
-bool xml_attribute::set_value(long long rhs);
-bool xml_attribute::set_value(unsigned long long rhs);
+
bool xml_attribute::set_value(int rhs);
+bool xml_attribute::set_value(unsigned int rhs);
+bool xml_attribute::set_value(long rhs);
+bool xml_attribute::set_value(unsigned long rhs);
+bool xml_attribute::set_value(double rhs);
+bool xml_attribute::set_value(double rhs, int precision);
+bool xml_attribute::set_value(float rhs);
+bool xml_attribute::set_value(float rhs, int precision);
+bool xml_attribute::set_value(bool rhs);
+bool xml_attribute::set_value(long long rhs);
+bool xml_attribute::set_value(unsigned long long rhs);
@@ -2640,16 +2712,16 @@ Number conversion functions depend on current C locale as set with setloca
-
xml_attribute& xml_attribute::operator=(const char_t* rhs);
-xml_attribute& xml_attribute::operator=(int rhs);
-xml_attribute& xml_attribute::operator=(unsigned int rhs);
-xml_attribute& xml_attribute::operator=(long rhs);
-xml_attribute& xml_attribute::operator=(unsigned long rhs);
-xml_attribute& xml_attribute::operator=(double rhs);
-xml_attribute& xml_attribute::operator=(float rhs);
-xml_attribute& xml_attribute::operator=(bool rhs);
-xml_attribute& xml_attribute::operator=(long long rhs);
-xml_attribute& xml_attribute::operator=(unsigned long long rhs);
+
xml_attribute& xml_attribute::operator=(const char_t* rhs);
+xml_attribute& xml_attribute::operator=(int rhs);
+xml_attribute& xml_attribute::operator=(unsigned int rhs);
+xml_attribute& xml_attribute::operator=(long rhs);
+xml_attribute& xml_attribute::operator=(unsigned long rhs);
+xml_attribute& xml_attribute::operator=(double rhs);
+xml_attribute& xml_attribute::operator=(float rhs);
+xml_attribute& xml_attribute::operator=(bool rhs);
+xml_attribute& xml_attribute::operator=(long long rhs);
+xml_attribute& xml_attribute::operator=(unsigned long long rhs);
@@ -2660,19 +2732,19 @@ Number conversion functions depend on current C locale as set with setloca
-
pugi::xml_attribute attr = node.attribute("id");
+
pugi::xml_attribute attr = node.attribute("id");
 
 // change attribute name/value
-std::cout << attr.set_name("key") << ", " << attr.set_value("345");
-std::cout << ", new attribute: " << attr.name() << "=" << attr.value() << std::endl;
+std::cout << attr.set_name("key") << ", " << attr.set_value("345");
+std::cout << ", new attribute: " << attr.name() << "=" << attr.value() << std::endl;
 
 // we can use numbers or booleans
-attr.set_value(1.234);
-std::cout << "new attribute value: " << attr.value() << std::endl;
+attr.set_value(1.234);
+std::cout << "new attribute value: " << attr.value() << std::endl;
 
 // we can also use assignment operators for more concise code
-attr = true;
-std::cout << "final attribute value: " << attr.value() << std::endl;
+attr = true; +std::cout << "final attribute value: " << attr.value() << std::endl;
@@ -2684,20 +2756,20 @@ Nodes and attributes do not exist without a document tree, so you can’t cr
-
xml_attribute xml_node::append_attribute(const char_t* name);
-xml_attribute xml_node::prepend_attribute(const char_t* name);
-xml_attribute xml_node::insert_attribute_after(const char_t* name, const xml_attribute& attr);
-xml_attribute xml_node::insert_attribute_before(const char_t* name, const xml_attribute& attr);
+
xml_attribute xml_node::append_attribute(const char_t* name);
+xml_attribute xml_node::prepend_attribute(const char_t* name);
+xml_attribute xml_node::insert_attribute_after(const char_t* name, const xml_attribute& attr);
+xml_attribute xml_node::insert_attribute_before(const char_t* name, const xml_attribute& attr);
 
-xml_node xml_node::append_child(xml_node_type type = node_element);
-xml_node xml_node::prepend_child(xml_node_type type = node_element);
-xml_node xml_node::insert_child_after(xml_node_type type, const xml_node& node);
-xml_node xml_node::insert_child_before(xml_node_type type, const xml_node& node);
+xml_node xml_node::append_child(xml_node_type type = node_element);
+xml_node xml_node::prepend_child(xml_node_type type = node_element);
+xml_node xml_node::insert_child_after(xml_node_type type, const xml_node& node);
+xml_node xml_node::insert_child_before(xml_node_type type, const xml_node& node);
 
-xml_node xml_node::append_child(const char_t* name);
-xml_node xml_node::prepend_child(const char_t* name);
-xml_node xml_node::insert_child_after(const char_t* name, const xml_node& node);
-xml_node xml_node::insert_child_before(const char_t* name, const xml_node& node);
+xml_node xml_node::append_child(const char_t* name); +xml_node xml_node::prepend_child(const char_t* name); +xml_node xml_node::insert_child_after(const char_t* name, const xml_node& node); +xml_node xml_node::insert_child_before(const char_t* name, const xml_node& node);
@@ -2755,19 +2827,19 @@ Nodes and attributes do not exist without a document tree, so you can’t cr
// add node with some name
-pugi::xml_node node = doc.append_child("node");
+pugi::xml_node node = doc.append_child("node");
 
 // add description node with text child
-pugi::xml_node descr = node.append_child("description");
-descr.append_child(pugi::node_pcdata).set_value("Simple node");
+pugi::xml_node descr = node.append_child("description");
+descr.append_child(pugi::node_pcdata).set_value("Simple node");
 
 // add param node before the description
-pugi::xml_node param = node.insert_child_before("param", descr);
+pugi::xml_node param = node.insert_child_before("param", descr);
 
 // add attributes to param node
-param.append_attribute("name") = "version";
-param.append_attribute("value") = 1.1;
-param.insert_attribute_after("type", param.attribute("name")) = "float";
+param.append_attribute("name") = "version"; +param.append_attribute("value") = 1.1; +param.insert_attribute_after("type", param.attribute("name")) = "float";
@@ -2779,10 +2851,10 @@ If you do not want your document to contain some node or attribute, you can remo
-
bool xml_node::remove_attribute(const xml_attribute& a);
-bool xml_node::remove_attributes();
-bool xml_node::remove_child(const xml_node& n);
-bool xml_node::remove_children();
+
bool xml_node::remove_attribute(const xml_attribute& a);
+bool xml_node::remove_attributes();
+bool xml_node::remove_child(const xml_node& n);
+bool xml_node::remove_children();
@@ -2809,8 +2881,8 @@ If you do not want your document to contain some node or attribute, you can remo
-
bool xml_node::remove_attribute(const char_t* name);
-bool xml_node::remove_child(const char_t* name);
+
bool xml_node::remove_attribute(const char_t* name);
+bool xml_node::remove_child(const char_t* name);
@@ -2822,16 +2894,16 @@ If you do not want your document to contain some node or attribute, you can remo
// remove description node with the whole subtree
-pugi::xml_node node = doc.child("node");
-node.remove_child("description");
+pugi::xml_node node = doc.child("node");
+node.remove_child("description");
 
 // remove id attribute
-pugi::xml_node param = node.child("param");
-param.remove_attribute("value");
+pugi::xml_node param = node.child("param");
+param.remove_attribute("value");
 
 // we can also remove nodes/attributes by handles
-pugi::xml_attribute id = param.attribute("name");
-param.remove_attribute(id);
+pugi::xml_attribute id = param.attribute("name"); +param.remove_attribute(id);
@@ -2845,7 +2917,7 @@ If you do not want your document to contain some node or attribute, you can remo
-
bool xml_text::set(const char_t* rhs);
+
bool xml_text::set(const char_t* rhs);
@@ -2856,17 +2928,17 @@ If you do not want your document to contain some node or attribute, you can remo
-
bool xml_text::set(int rhs);
-bool xml_text::set(unsigned int rhs);
-bool xml_text::set(long rhs);
-bool xml_text::set(unsigned long rhs);
-bool xml_text::set(double rhs);
-bool xml_text::set(double rhs, int precision);
-bool xml_text::set(float rhs);
-bool xml_text::set(float rhs, int precision);
-bool xml_text::set(bool rhs);
-bool xml_text::set(long long rhs);
-bool xml_text::set(unsigned long long rhs);
+
bool xml_text::set(int rhs);
+bool xml_text::set(unsigned int rhs);
+bool xml_text::set(long rhs);
+bool xml_text::set(unsigned long rhs);
+bool xml_text::set(double rhs);
+bool xml_text::set(double rhs, int precision);
+bool xml_text::set(float rhs);
+bool xml_text::set(float rhs, int precision);
+bool xml_text::set(bool rhs);
+bool xml_text::set(long long rhs);
+bool xml_text::set(unsigned long long rhs);
@@ -2877,16 +2949,16 @@ If you do not want your document to contain some node or attribute, you can remo
-
xml_text& xml_text::operator=(const char_t* rhs);
-xml_text& xml_text::operator=(int rhs);
-xml_text& xml_text::operator=(unsigned int rhs);
-xml_text& xml_text::operator=(long rhs);
-xml_text& xml_text::operator=(unsigned long rhs);
-xml_text& xml_text::operator=(double rhs);
-xml_text& xml_text::operator=(float rhs);
-xml_text& xml_text::operator=(bool rhs);
-xml_text& xml_text::operator=(long long rhs);
-xml_text& xml_text::operator=(unsigned long long rhs);
+
xml_text& xml_text::operator=(const char_t* rhs);
+xml_text& xml_text::operator=(int rhs);
+xml_text& xml_text::operator=(unsigned int rhs);
+xml_text& xml_text::operator=(long rhs);
+xml_text& xml_text::operator=(unsigned long rhs);
+xml_text& xml_text::operator=(double rhs);
+xml_text& xml_text::operator=(float rhs);
+xml_text& xml_text::operator=(bool rhs);
+xml_text& xml_text::operator=(long long rhs);
+xml_text& xml_text::operator=(unsigned long long rhs);
@@ -2898,11 +2970,11 @@ If you do not want your document to contain some node or attribute, you can remo
// change project version
-project.child("version").text() = 1.2;
+project.child("version").text() = 1.2;
 
 // add description element and set the contents
 // note that we do not have to explicitly add the node_pcdata child
-project.append_child("description").text().set("a test project");
+project.append_child("description").text().set("a test project");
@@ -2914,15 +2986,15 @@ With the help of previously described functions, it is possible to create trees
-
xml_attribute xml_node::append_copy(const xml_attribute& proto);
-xml_attribute xml_node::prepend_copy(const xml_attribute& proto);
-xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr);
-xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr);
+
xml_attribute xml_node::append_copy(const xml_attribute& proto);
+xml_attribute xml_node::prepend_copy(const xml_attribute& proto);
+xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr);
+xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr);
 
-xml_node xml_node::append_copy(const xml_node& proto);
-xml_node xml_node::prepend_copy(const xml_node& proto);
-xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node);
-xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node);
+xml_node xml_node::append_copy(const xml_node& proto); +xml_node xml_node::prepend_copy(const xml_node& proto); +xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node); +xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node);
@@ -2952,53 +3024,53 @@ With the help of previously described functions, it is possible to create trees
-
bool load_preprocess(pugi::xml_document& doc, const char* path);
+
bool load_preprocess(pugi::xml_document& doc, const char* path);
 
-bool preprocess(pugi::xml_node node)
-{
-    for (pugi::xml_node child = node.first_child(); child; )
-    {
-        if (child.type() == pugi::node_pi && strcmp(child.name(), "include") == 0)
-        {
-            pugi::xml_node include = child;
+bool preprocess(pugi::xml_node node)
+{
+    for (pugi::xml_node child = node.first_child(); child; )
+    {
+        if (child.type() == pugi::node_pi && strcmp(child.name(), "include") == 0)
+        {
+            pugi::xml_node include = child;
 
-            // load new preprocessed document (note: ideally this should handle relative paths)
-            const char* path = include.value();
+            // load new preprocessed document (note: ideally this should handle relative paths)
+            const char* path = include.value();
 
-            pugi::xml_document doc;
-            if (!load_preprocess(doc, path)) return false;
+            pugi::xml_document doc;
+            if (!load_preprocess(doc, path)) return false;
 
-            // insert the comment marker above include directive
-            node.insert_child_before(pugi::node_comment, include).set_value(path);
+            // insert the comment marker above include directive
+            node.insert_child_before(pugi::node_comment, include).set_value(path);
 
-            // copy the document above the include directive (this retains the original order!)
-            for (pugi::xml_node ic = doc.first_child(); ic; ic = ic.next_sibling())
-            {
-                node.insert_copy_before(ic, include);
-            }
+            // copy the document above the include directive (this retains the original order!)
+            for (pugi::xml_node ic = doc.first_child(); ic; ic = ic.next_sibling())
+            {
+                node.insert_copy_before(ic, include);
+            }
 
-            // remove the include node and move to the next child
-            child = child.next_sibling();
+            // remove the include node and move to the next child
+            child = child.next_sibling();
 
-            node.remove_child(include);
-        }
-        else
-        {
-            if (!preprocess(child)) return false;
+            node.remove_child(include);
+        }
+        else
+        {
+            if (!preprocess(child)) return false;
 
-            child = child.next_sibling();
-        }
-    }
+            child = child.next_sibling();
+        }
+    }
 
-    return true;
-}
+    return true;
+}
 
-bool load_preprocess(pugi::xml_document& doc, const char* path)
-{
-    pugi::xml_parse_result result = doc.load_file(path, pugi::parse_default | pugi::parse_pi); // for <?include?>
+bool load_preprocess(pugi::xml_document& doc, const char* path)
+{
+    pugi::xml_parse_result result = doc.load_file(path, pugi::parse_default | pugi::parse_pi); // for <?include?>
 
-    return result ? preprocess(doc) : false;
-}
+ return result ? preprocess(doc) : false; +}
@@ -3010,10 +3082,10 @@ Sometimes instead of cloning a node you need to move an existing node to a diffe
-
xml_node xml_node::append_move(const xml_node& moved);
-xml_node xml_node::prepend_move(const xml_node& moved);
-xml_node xml_node::insert_move_after(const xml_node& moved, const xml_node& node);
-xml_node xml_node::insert_move_before(const xml_node& moved, const xml_node& node);
+
xml_node xml_node::append_move(const xml_node& moved);
+xml_node xml_node::prepend_move(const xml_node& moved);
+xml_node xml_node::insert_move_after(const xml_node& moved, const xml_node& node);
+xml_node xml_node::insert_move_before(const xml_node& moved, const xml_node& node);
@@ -3050,14 +3122,14 @@ Sometimes instead of cloning a node you need to move an existing node to a diffe

Use a temporary document to parse the data from a string, then clone the nodes to a destination node. For example:

-
bool append_fragment(pugi::xml_node target, const char* buffer, size_t size)
-{
-    pugi::xml_document doc;
-    if (!doc.load_buffer(buffer, size)) return false;
+
bool append_fragment(pugi::xml_node target, const char* buffer, size_t size)
+{
+    pugi::xml_document doc;
+    if (!doc.load_buffer(buffer, size)) return false;
 
-    for (pugi::xml_node child = doc.first_child(); child; child = child.next_sibling())
-        target.append_copy(child);
-}
+ for (pugi::xml_node child = doc.first_child(); child; child = child.next_sibling()) + target.append_copy(child); +}
@@ -3065,11 +3137,11 @@ Sometimes instead of cloning a node you need to move an existing node to a diffe

Cache the parsing step - instead of keeping in-memory buffers, keep document objects that already contain the parsed fragment:

-
bool append_fragment(pugi::xml_node target, const pugi::xml_document& cached_fragment)
-{
-    for (pugi::xml_node child = cached_fragment.first_child(); child; child = child.next_sibling())
-        target.append_copy(child);
-}
+
bool append_fragment(pugi::xml_node target, const pugi::xml_document& cached_fragment)
+{
+    for (pugi::xml_node child = cached_fragment.first_child(); child; child = child.next_sibling())
+        target.append_copy(child);
+}
@@ -3077,7 +3149,7 @@ Sometimes instead of cloning a node you need to move an existing node to a diffe

Use xml_node::append_buffer directly:

-
xml_parse_result xml_node::append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+
xml_parse_result xml_node::append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
@@ -3115,18 +3187,18 @@ If you want to save the whole document to a file, you can use one of the followi
-
bool xml_document::save_file(const char* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
-bool xml_document::save_file(const wchar_t* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
+
bool xml_document::save_file(const char* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
+bool xml_document::save_file(const wchar_t* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
-

These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see Output options) and output data encoding (see Encodings). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc.

+

These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see Output options) and output data encoding (see Encodings). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc. The functions return true on success and false if the file could not be opened or written to.

File path is passed to the system file opening function as is in case of the first function (which accepts const char* path); the second function either uses a special file opening function if it is provided by the runtime library or converts the path to UTF-8 and uses the system file opening function.

-

save_file opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. If the file could not be opened, the function returns false. Calling save_file is equivalent to creating an xml_writer_file object with FILE* handle as the only constructor argument and then calling save; see Saving document via writer interface for writer interface details.

+

save_file opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. Calling save_file is equivalent to creating an xml_writer_file object with FILE* handle as the only constructor argument and then calling save; see Saving document via writer interface for writer interface details.

This is a simple example of saving XML document to file (samples/save_file.cpp):

@@ -3134,7 +3206,7 @@ If you want to save the whole document to a file, you can use one of the followi
// save document to file
-std::cout << "Saving result: " << doc.save_file("save_file_output.xml") << std::endl;
+std::cout << "Saving result: " << doc.save_file("save_file_output.xml") << std::endl;
@@ -3145,8 +3217,8 @@ If you want to save the whole document to a file, you can use one of the followi
-
void xml_document::save(std::ostream& stream, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
-void xml_document::save(std::wostream& stream, const char_t* indent = "\t", unsigned int flags = format_default) const;
+
void xml_document::save(std::ostream& stream, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
+void xml_document::save(std::wostream& stream, const char_t* indent = "\t", unsigned int flags = format_default) const;
@@ -3161,8 +3233,8 @@ If you want to save the whole document to a file, you can use one of the followi
// save document to standard output
-std::cout << "Document:\n";
-doc.save(std::cout);
+std::cout << "Document:\n"; +doc.save(std::cout);
@@ -3174,13 +3246,13 @@ All of the above saving functions are implemented in terms of writer interface.
-
class xml_writer
-{
-public:
-    virtual void write(const void* data, size_t size) = 0;
-};
+
class xml_writer
+{
+public:
+    virtual void write(const void* data, size_t size) = 0;
+};
 
-void xml_document::save(xml_writer& writer, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
+void xml_document::save(xml_writer& writer, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
@@ -3194,15 +3266,15 @@ All of the above saving functions are implemented in terms of writer interface.
-
struct xml_string_writer: pugi::xml_writer
-{
-    std::string result;
+
struct xml_string_writer: pugi::xml_writer
+{
+    std::string result;
 
-    virtual void write(const void* data, size_t size)
-    {
-        result.append(static_cast<const char*>(data), size);
-    }
-};
+ virtual void write(const void* data, size_t size) + { + result.append(static_cast<const char*>(data), size); + } +};
@@ -3214,9 +3286,9 @@ While the previously described functions save the whole document to the destinat
-
void xml_node::print(std::ostream& os, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
-void xml_node::print(std::wostream& os, const char_t* indent = "\t", unsigned int flags = format_default, unsigned int depth = 0) const;
-void xml_node::print(xml_writer& writer, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
+
void xml_node::print(std::ostream& os, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
+void xml_node::print(std::wostream& os, const char_t* indent = "\t", unsigned int flags = format_default, unsigned int depth = 0) const;
+void xml_node::print(xml_writer& writer, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
@@ -3228,20 +3300,20 @@ While the previously described functions save the whole document to the destinat
// get a test document
-pugi::xml_document doc;
-doc.load_string("<foo bar='baz'><call>hey</call></foo>");
+pugi::xml_document doc;
+doc.load_string("<foo bar='baz'><call>hey</call></foo>");
 
 // print document to standard output (prints <?xml version="1.0"?><foo bar="baz"><call>hey</call></foo>)
-doc.save(std::cout, "", pugi::format_raw);
-std::cout << std::endl;
+doc.save(std::cout, "", pugi::format_raw);
+std::cout << std::endl;
 
 // print document to standard output as a regular node (prints <foo bar="baz"><call>hey</call></foo>)
-doc.print(std::cout, "", pugi::format_raw);
-std::cout << std::endl;
+doc.print(std::cout, "", pugi::format_raw);
+std::cout << std::endl;
 
 // print a subtree to standard output (prints <call>hey</call>)
-doc.child("foo").child("call").print(std::cout, "", pugi::format_raw);
-std::cout << std::endl;
+doc.child("foo").child("call").print(std::cout, "", pugi::format_raw); +std::cout << std::endl;
@@ -3323,42 +3395,42 @@ contain platform-independent newline \n (ASCII 10). If this flag is
// get a test document
-pugi::xml_document doc;
-doc.load_string("<foo bar='baz'><call>hey</call></foo>");
+pugi::xml_document doc;
+doc.load_string("<foo bar='baz'><call>hey</call></foo>");
 
 // default options; prints
 // <?xml version="1.0"?>
 // <foo bar="baz">
 //         <call>hey</call>
 // </foo>
-doc.save(std::cout);
-std::cout << std::endl;
+doc.save(std::cout);
+std::cout << std::endl;
 
 // default options with custom indentation string; prints
 // <?xml version="1.0"?>
 // <foo bar="baz">
 // --<call>hey</call>
 // </foo>
-doc.save(std::cout, "--");
-std::cout << std::endl;
+doc.save(std::cout, "--");
+std::cout << std::endl;
 
 // default options without indentation; prints
 // <?xml version="1.0"?>
 // <foo bar="baz">
 // <call>hey</call>
 // </foo>
-doc.save(std::cout, "\t", pugi::format_default & ~pugi::format_indent); // can also pass "" instead of indentation string for the same effect
-std::cout << std::endl;
+doc.save(std::cout, "\t", pugi::format_default & ~pugi::format_indent); // can also pass "" instead of indentation string for the same effect
+std::cout << std::endl;
 
 // raw output; prints
 // <?xml version="1.0"?><foo bar="baz"><call>hey</call></foo>
-doc.save(std::cout, "\t", pugi::format_raw);
-std::cout << std::endl << std::endl;
+doc.save(std::cout, "\t", pugi::format_raw);
+std::cout << std::endl << std::endl;
 
 // raw output without declaration; prints
 // <foo bar="baz"><call>hey</call></foo>
-doc.save(std::cout, "\t", pugi::format_raw | pugi::format_no_declaration);
-std::cout << std::endl;
+doc.save(std::cout, "\t", pugi::format_raw | pugi::format_no_declaration); +std::cout << std::endl;
@@ -3412,21 +3484,21 @@ By default the declaration node is not added to the document during parsing. If
// get a test document
-pugi::xml_document doc;
-doc.load_string("<foo bar='baz'><call>hey</call></foo>");
+pugi::xml_document doc;
+doc.load_string("<foo bar='baz'><call>hey</call></foo>");
 
 // add a custom declaration node
-pugi::xml_node decl = doc.prepend_child(pugi::node_declaration);
-decl.append_attribute("version") = "1.0";
-decl.append_attribute("encoding") = "UTF-8";
-decl.append_attribute("standalone") = "no";
+pugi::xml_node decl = doc.prepend_child(pugi::node_declaration);
+decl.append_attribute("version") = "1.0";
+decl.append_attribute("encoding") = "UTF-8";
+decl.append_attribute("standalone") = "no";
 
 // <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 // <foo bar="baz">
 //         <call>hey</call>
 // </foo>
-doc.save(std::cout);
-std::cout << std::endl;
+doc.save(std::cout); +std::cout << std::endl;
@@ -3450,8 +3522,8 @@ Because an XPath node can be either a node or an attribute, there is a special t
-
xml_node xpath_node::node() const;
-xml_attribute xpath_node::attribute() const;
+
xml_node xpath_node::node() const;
+xml_attribute xpath_node::attribute() const;
@@ -3462,7 +3534,7 @@ Because an XPath node can be either a node or an attribute, there is a special t
-
xml_node xpath_node::parent() const;
+
xml_node xpath_node::parent() const;
@@ -3484,9 +3556,9 @@ Node sets are represented by xpath_node_set object, which has an in
-
typedef const xpath_node* xpath_node_set::const_iterator;
-const_iterator xpath_node_set::begin() const;
-const_iterator xpath_node_set::end() const;
+
typedef const xpath_node* xpath_node_set::const_iterator;
+const_iterator xpath_node_set::begin() const;
+const_iterator xpath_node_set::end() const;
@@ -3495,9 +3567,9 @@ And it also can be iterated via indices, just like std::vector:

-
const xpath_node& xpath_node_set::operator[](size_t index) const;
-size_t xpath_node_set::size() const;
-bool xpath_node_set::empty() const;
+
const xpath_node& xpath_node_set::operator[](size_t index) const;
+size_t xpath_node_set::size() const;
+bool xpath_node_set::empty() const;
@@ -3509,8 +3581,8 @@ The order of iteration depends on the order of nodes inside the set; the order c
-
enum xpath_node_set::type_t {type_unsorted, type_sorted, type_sorted_reverse};
-type_t xpath_node_set::type() const;
+
enum xpath_node_set::type_t {type_unsorted, type_sorted, type_sorted_reverse};
+type_t xpath_node_set::type() const;
@@ -3518,7 +3590,7 @@ The order of iteration depends on the order of nodes inside the set; the order c
-
void xpath_node_set::sort(bool reverse = false);
+
void xpath_node_set::sort(bool reverse = false);
@@ -3529,7 +3601,7 @@ The order of iteration depends on the order of nodes inside the set; the order c
-
xpath_node xpath_node_set::first() const;
+
xpath_node xpath_node_set::first() const;
@@ -3540,7 +3612,7 @@ The order of iteration depends on the order of nodes inside the set; the order c
-
xpath_node_set::xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted);
+
xpath_node_set::xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted);
@@ -3555,8 +3627,8 @@ If you want to select nodes that match some XPath expression, you can do it with
-
xpath_node xml_node::select_node(const char_t* query, xpath_variable_set* variables = 0) const;
-xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables = 0) const;
+
xpath_node xml_node::select_node(const char_t* query, xpath_variable_set* variables = 0) const;
+xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables = 0) const;
@@ -3571,8 +3643,8 @@ While compiling expressions is fast, the compilation time can introduce a signif
-
xpath_node xml_node::select_node(const xpath_query& query) const;
-xpath_node_set xml_node::select_nodes(const xpath_query& query) const;
+
xpath_node xml_node::select_node(const xpath_query& query) const;
+xpath_node_set xml_node::select_nodes(const xpath_query& query) const;
@@ -3583,20 +3655,20 @@ While compiling expressions is fast, the compilation time can introduce a signif
-
pugi::xpath_node_set tools = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']");
+
pugi::xpath_node_set tools = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']");
 
-std::cout << "Tools:\n";
+std::cout << "Tools:\n";
 
-for (pugi::xpath_node_set::const_iterator it = tools.begin(); it != tools.end(); ++it)
-{
-    pugi::xpath_node node = *it;
-    std::cout << node.node().attribute("Filename").value() << "\n";
-}
+for (pugi::xpath_node_set::const_iterator it = tools.begin(); it != tools.end(); ++it)
+{
+    pugi::xpath_node node = *it;
+    std::cout << node.node().attribute("Filename").value() << "\n";
+}
 
-pugi::xpath_node build_tool = doc.select_node("//Tool[contains(Description, 'build system')]");
+pugi::xpath_node build_tool = doc.select_node("//Tool[contains(Description, 'build system')]");
 
-if (build_tool)
-    std::cout << "Build tool: " << build_tool.node().attribute("Filename").value() << "\n";
+if (build_tool) + std::cout << "Build tool: " << build_tool.node().attribute("Filename").value() << "\n";
@@ -3626,7 +3698,7 @@ While compiling expressions is fast, the compilation time can introduce a signif
-
explicit xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables = 0);
+
explicit xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables = 0);
@@ -3634,7 +3706,7 @@ While compiling expressions is fast, the compilation time can introduce a signif
-
xpath_value_type xpath_query::return_type() const;
+
xpath_value_type xpath_query::return_type() const;
@@ -3643,11 +3715,11 @@ You can evaluate the query using one of the following functions:

-
bool xpath_query::evaluate_boolean(const xpath_node& n) const;
-double xpath_query::evaluate_number(const xpath_node& n) const;
-string_t xpath_query::evaluate_string(const xpath_node& n) const;
-xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const;
-xpath_node xpath_query::evaluate_node(const xpath_node& n) const;
+
bool xpath_query::evaluate_boolean(const xpath_node& n) const;
+double xpath_query::evaluate_number(const xpath_node& n) const;
+string_t xpath_query::evaluate_string(const xpath_node& n) const;
+xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const;
+xpath_node xpath_query::evaluate_node(const xpath_node& n) const;
@@ -3670,7 +3742,7 @@ Calling node.select_nodes("query") is equivalent to calling x
-
size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const;
+
size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const;
@@ -3692,26 +3764,26 @@ Calling node.select_nodes("query") is equivalent to calling x
// Select nodes via compiled query
-pugi::xpath_query query_remote_tools("/Profile/Tools/Tool[@AllowRemote='true']");
+pugi::xpath_query query_remote_tools("/Profile/Tools/Tool[@AllowRemote='true']");
 
-pugi::xpath_node_set tools = query_remote_tools.evaluate_node_set(doc);
-std::cout << "Remote tool: ";
-tools[2].node().print(std::cout);
+pugi::xpath_node_set tools = query_remote_tools.evaluate_node_set(doc);
+std::cout << "Remote tool: ";
+tools[2].node().print(std::cout);
 
 // Evaluate numbers via compiled query
-pugi::xpath_query query_timeouts("sum(//Tool/@Timeout)");
-std::cout << query_timeouts.evaluate_number(doc) << std::endl;
+pugi::xpath_query query_timeouts("sum(//Tool/@Timeout)");
+std::cout << query_timeouts.evaluate_number(doc) << std::endl;
 
 // Evaluate strings via compiled query for different context nodes
-pugi::xpath_query query_name_valid("string-length(substring-before(@Filename, '_')) > 0 and @OutputFileMasks");
-pugi::xpath_query query_name("concat(substring-before(@Filename, '_'), ' produces ', @OutputFileMasks)");
+pugi::xpath_query query_name_valid("string-length(substring-before(@Filename, '_')) > 0 and @OutputFileMasks");
+pugi::xpath_query query_name("concat(substring-before(@Filename, '_'), ' produces ', @OutputFileMasks)");
 
-for (pugi::xml_node tool = doc.first_element_by_path("Profile/Tools/Tool"); tool; tool = tool.next_sibling())
-{
-    std::string s = query_name.evaluate_string(tool);
+for (pugi::xml_node tool = doc.first_element_by_path("Profile/Tools/Tool"); tool; tool = tool.next_sibling())
+{
+    std::string s = query_name.evaluate_string(tool);
 
-    if (query_name_valid.evaluate_boolean(tool)) std::cout << s << std::endl;
-}
+ if (query_name_valid.evaluate_boolean(tool)) std::cout << s << std::endl; +}
@@ -3725,9 +3797,9 @@ Calling node.select_nodes("query") is equivalent to calling x
-
explicit xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables = 0);
-xpath_node xml_node::select_node(const char_t* query, xpath_variable_set* variables = 0) const;
-xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables = 0) const;
+
explicit xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables = 0);
+xpath_node xml_node::select_node(const char_t* query, xpath_variable_set* variables = 0) const;
+xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables = 0) const;
@@ -3753,7 +3825,7 @@ The variable set pointer is stored in the query object; you have to ensure that
-
xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type);
+
xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type);
@@ -3767,8 +3839,8 @@ The variable set pointer is stored in the query object; you have to ensure that
-
xpath_variable* xpath_variable_set::get(const char_t* name);
-const xpath_variable* xpath_variable_set::get(const char_t* name) const;
+
xpath_variable* xpath_variable_set::get(const char_t* name);
+const xpath_variable* xpath_variable_set::get(const char_t* name) const;
@@ -3779,10 +3851,10 @@ The variable set pointer is stored in the query object; you have to ensure that
-
bool xpath_variable_set::set(const char_t* name, bool value);
-bool xpath_variable_set::set(const char_t* name, double value);
-bool xpath_variable_set::set(const char_t* name, const char_t* value);
-bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value);
+
bool xpath_variable_set::set(const char_t* name, bool value);
+bool xpath_variable_set::set(const char_t* name, double value);
+bool xpath_variable_set::set(const char_t* name, const char_t* value);
+bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value);
@@ -3797,8 +3869,8 @@ In order to get variable information, you can use one of the following functions
-
const char_t* xpath_variable::name() const;
-xpath_value_type xpath_variable::type() const;
+
const char_t* xpath_variable::name() const;
+xpath_value_type xpath_variable::type() const;
@@ -3810,10 +3882,10 @@ In order to get variable value, you should use one of the following functions, d
-
bool xpath_variable::get_boolean() const;
-double xpath_variable::get_number() const;
-const char_t* xpath_variable::get_string() const;
-const xpath_node_set& xpath_variable::get_node_set() const;
+
bool xpath_variable::get_boolean() const;
+double xpath_variable::get_number() const;
+const char_t* xpath_variable::get_string() const;
+const xpath_node_set& xpath_variable::get_node_set() const;
@@ -3824,10 +3896,10 @@ In order to get variable value, you should use one of the following functions, d
-
bool xpath_variable::set(bool value);
-bool xpath_variable::set(double value);
-bool xpath_variable::set(const char_t* value);
-bool xpath_variable::set(const xpath_node_set& value);
+
bool xpath_variable::set(bool value);
+bool xpath_variable::set(double value);
+bool xpath_variable::set(const char_t* value);
+bool xpath_variable::set(const xpath_node_set& value);
@@ -3839,28 +3911,28 @@ In order to get variable value, you should use one of the following functions, d
// Select nodes via compiled query
-pugi::xpath_variable_set vars;
-vars.add("remote", pugi::xpath_type_boolean);
+pugi::xpath_variable_set vars;
+vars.add("remote", pugi::xpath_type_boolean);
 
-pugi::xpath_query query_remote_tools("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars);
+pugi::xpath_query query_remote_tools("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars);
 
-vars.set("remote", true);
-pugi::xpath_node_set tools_remote = query_remote_tools.evaluate_node_set(doc);
+vars.set("remote", true);
+pugi::xpath_node_set tools_remote = query_remote_tools.evaluate_node_set(doc);
 
-vars.set("remote", false);
-pugi::xpath_node_set tools_local = query_remote_tools.evaluate_node_set(doc);
+vars.set("remote", false);
+pugi::xpath_node_set tools_local = query_remote_tools.evaluate_node_set(doc);
 
-std::cout << "Remote tool: ";
-tools_remote[2].node().print(std::cout);
+std::cout << "Remote tool: ";
+tools_remote[2].node().print(std::cout);
 
-std::cout << "Local tool: ";
-tools_local[0].node().print(std::cout);
+std::cout << "Local tool: ";
+tools_local[0].node().print(std::cout);
 
 // You can pass the context directly to select_nodes/select_node
-pugi::xpath_node_set tools_local_imm = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars);
+pugi::xpath_node_set tools_local_imm = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars);
 
-std::cout << "Local tool imm: ";
-tools_local_imm[0].node().print(std::cout);
+std::cout << "Local tool imm: "; +tools_local_imm[0].node().print(std::cout);
@@ -3875,8 +3947,8 @@ By default, XPath functions throw xpath_exception object in case of
-
virtual const char* xpath_exception::what() const throw();
-const xpath_parse_result& xpath_exception::result() const;
+
virtual const char* xpath_exception::what() const throw();
+const xpath_parse_result& xpath_exception::result() const;
@@ -3885,7 +3957,7 @@ If exceptions are disabled, then in the event of parsing failure the query is in
-
const xpath_parse_result& xpath_query::result() const;
+
const xpath_parse_result& xpath_query::result() const;
@@ -3896,14 +3968,14 @@ If exceptions are disabled, then in the event of parsing failure the query is in
-
struct xpath_parse_result
-{
-    const char* error;
-    ptrdiff_t offset;
+
struct xpath_parse_result
+{
+    const char* error;
+    ptrdiff_t offset;
 
-    operator bool() const;
-    const char* description() const;
-};
+ operator bool() const; + const char* description() const; +};
@@ -3924,34 +3996,34 @@ If exceptions are disabled, then in the event of parsing failure the query is in
// Exception is thrown for incorrect query syntax
-try
-{
-    doc.select_nodes("//nodes[#true()]");
-}
-catch (const pugi::xpath_exception& e)
-{
-    std::cout << "Select failed: " << e.what() << std::endl;
-}
+try
+{
+    doc.select_nodes("//nodes[#true()]");
+}
+catch (const pugi::xpath_exception& e)
+{
+    std::cout << "Select failed: " << e.what() << std::endl;
+}
 
 // Exception is thrown for incorrect query semantics
-try
-{
-    doc.select_nodes("(123)/next");
-}
-catch (const pugi::xpath_exception& e)
-{
-    std::cout << "Select failed: " << e.what() << std::endl;
-}
+try
+{
+    doc.select_nodes("(123)/next");
+}
+catch (const pugi::xpath_exception& e)
+{
+    std::cout << "Select failed: " << e.what() << std::endl;
+}
 
 // Exception is thrown for query with incorrect return type
-try
-{
-    doc.select_nodes("123");
-}
-catch (const pugi::xpath_exception& e)
-{
-    std::cout << "Select failed: " << e.what() << std::endl;
-}
+try +{ + doc.select_nodes("123"); +} +catch (const pugi::xpath_exception& e) +{ + std::cout << "Select failed: " << e.what() << std::endl; +}
@@ -3986,6 +4058,68 @@ If exceptions are disabled, then in the event of parsing failure the query is in

9. Changelog

+

v1.12 2022-02-09

+
+

Maintenance release. Changes:

+
+
+
    +
  • +

    Bug fixes:

    +
    +
      +
    1. +

      Fix a bug in xml_document move construction when the source of the move is empty

      +
    2. +
    3. +

      Fix const-correctness issues with iterator objects to support C++20 ranges

      +
    4. +
    +
    +
  • +
  • +

    XPath improvements:

    +
    +
      +
    1. +

      Improved detection of overly complex queries that may result in stack overflow during parsing

      +
    2. +
    +
    +
  • +
  • +

    Compatibility improvements:

    +
    +
      +
    1. +

      Fix Cygwin support for DLL builds

      +
    2. +
    3. +

      Fix Windows CE support

      +
    4. +
    5. +

      Add NuGet builds and project files for VS2022

      +
    6. +
    +
    +
  • +
  • +

    Build system changes

    +
    +
      +
    1. +

      All CMake options now have the prefix PUGIXML_. This may require changing dependent build configurations.

      +
    2. +
    3. +

      Many build settings are now exposed via CMake settings, most notably PUGIXML_COMPACT and PUGIXML_WCHAR_MODE can be set without changing pugiconfig.hpp

      +
    4. +
    +
    +
  • +
+
+
+

v1.11 2020-11-26

Maintenance release. Changes:

@@ -4034,6 +4168,16 @@ If exceptions are disabled, then in the event of parsing failure the query is in
+
  • +

    Build system changes

    +
    +
      +
    1. +

      The CMake package for pugixml now provides a pugixml::pugixml target rather than a pugixml target. A compatibility pugixml target is provided if at least version 1.11 is not requested.

      +
    2. +
    +
    +
  • @@ -5383,10 +5527,10 @@ If exceptions are disabled, then in the event of parsing failure the query is in

    10.2. Types

    -
    typedef configuration-defined-type char_t;
    -typedef configuration-defined-type string_t;
    -typedef void* (*allocation_function)(size_t size);
    -typedef void (*deallocation_function)(void* ptr);
    +
    typedef configuration-defined-type char_t;
    +typedef configuration-defined-type string_t;
    +typedef void* (*allocation_function)(size_t size);
    +typedef void (*deallocation_function)(void* ptr);
    @@ -5394,54 +5538,54 @@ If exceptions are disabled, then in the event of parsing failure the query is in

    10.3. Enumerations

    -
    enum xml_node_type
    -    node_null
    -    node_document
    -    node_element
    -    node_pcdata
    -    node_cdata
    -    node_comment
    -    node_pi
    -    node_declaration
    -    node_doctype
    +
    enum xml_node_type
    +    node_null
    +    node_document
    +    node_element
    +    node_pcdata
    +    node_cdata
    +    node_comment
    +    node_pi
    +    node_declaration
    +    node_doctype
     
    -enum xml_parse_status
    -    status_ok
    -    status_file_not_found
    -    status_io_error
    -    status_out_of_memory
    -    status_internal_error
    -    status_unrecognized_tag
    -    status_bad_pi
    -    status_bad_comment
    -    status_bad_cdata
    -    status_bad_doctype
    -    status_bad_pcdata
    -    status_bad_start_element
    -    status_bad_attribute
    -    status_bad_end_element
    -    status_end_element_mismatch
    -    status_append_invalid_root
    -    status_no_document_element
    +enum xml_parse_status
    +    status_ok
    +    status_file_not_found
    +    status_io_error
    +    status_out_of_memory
    +    status_internal_error
    +    status_unrecognized_tag
    +    status_bad_pi
    +    status_bad_comment
    +    status_bad_cdata
    +    status_bad_doctype
    +    status_bad_pcdata
    +    status_bad_start_element
    +    status_bad_attribute
    +    status_bad_end_element
    +    status_end_element_mismatch
    +    status_append_invalid_root
    +    status_no_document_element
     
    -enum xml_encoding
    -    encoding_auto
    -    encoding_utf8
    -    encoding_utf16_le
    -    encoding_utf16_be
    -    encoding_utf16
    -    encoding_utf32_le
    -    encoding_utf32_be
    -    encoding_utf32
    -    encoding_wchar
    -    encoding_latin1
    +enum xml_encoding
    +    encoding_auto
    +    encoding_utf8
    +    encoding_utf16_le
    +    encoding_utf16_be
    +    encoding_utf16
    +    encoding_utf32_le
    +    encoding_utf32_be
    +    encoding_utf32
    +    encoding_wchar
    +    encoding_latin1
     
    -enum xpath_value_type
    -    xpath_type_none
    -    xpath_type_node_set
    -    xpath_type_number
    -    xpath_type_string
    -    xpath_type_boolean
    +enum xpath_value_type + xpath_type_none + xpath_type_node_set + xpath_type_number + xpath_type_string + xpath_type_boolean
    @@ -5450,36 +5594,36 @@ If exceptions are disabled, then in the event of parsing failure the query is in
    // Formatting options bit flags:
    -const unsigned int format_attribute_single_quote
    -const unsigned int format_default
    -const unsigned int format_indent
    -const unsigned int format_indent_attributes
    -const unsigned int format_no_declaration
    -const unsigned int format_no_empty_element_tags
    -const unsigned int format_no_escapes
    -const unsigned int format_raw
    -const unsigned int format_save_file_text
    -const unsigned int format_skip_control_chars
    -const unsigned int format_write_bom
    +const unsigned int format_attribute_single_quote
    +const unsigned int format_default
    +const unsigned int format_indent
    +const unsigned int format_indent_attributes
    +const unsigned int format_no_declaration
    +const unsigned int format_no_empty_element_tags
    +const unsigned int format_no_escapes
    +const unsigned int format_raw
    +const unsigned int format_save_file_text
    +const unsigned int format_skip_control_chars
    +const unsigned int format_write_bom
     
     // Parsing options bit flags:
    -const unsigned int parse_cdata
    -const unsigned int parse_comments
    -const unsigned int parse_declaration
    -const unsigned int parse_default
    -const unsigned int parse_doctype
    -const unsigned int parse_eol
    -const unsigned int parse_escapes
    -const unsigned int parse_fragment
    -const unsigned int parse_full
    -const unsigned int parse_minimal
    -const unsigned int parse_pi
    -const unsigned int parse_trim_pcdata
    -const unsigned int parse_ws_pcdata
    -const unsigned int parse_ws_pcdata_single
    -const unsigned int parse_embed_pcdata
    -const unsigned int parse_wconv_attribute
    -const unsigned int parse_wnorm_attribute
    +const unsigned int parse_cdata +const unsigned int parse_comments +const unsigned int parse_declaration +const unsigned int parse_default +const unsigned int parse_doctype +const unsigned int parse_eol +const unsigned int parse_escapes +const unsigned int parse_fragment +const unsigned int parse_full +const unsigned int parse_minimal +const unsigned int parse_pi +const unsigned int parse_trim_pcdata +const unsigned int parse_ws_pcdata +const unsigned int parse_ws_pcdata_single +const unsigned int parse_embed_pcdata +const unsigned int parse_wconv_attribute +const unsigned int parse_wnorm_attribute
    @@ -5487,352 +5631,352 @@ If exceptions are disabled, then in the event of parsing failure the query is in

    10.5. Classes

    -
    class xml_attribute
    -    xml_attribute();
    -
    -    bool empty() const;
    -    operator unspecified_bool_type() const;
    -
    -    bool operator==(const xml_attribute& r) const;
    -    bool operator!=(const xml_attribute& r) const;
    -    bool operator<(const xml_attribute& r) const;
    -    bool operator>(const xml_attribute& r) const;
    -    bool operator<=(const xml_attribute& r) const;
    -    bool operator>=(const xml_attribute& r) const;
    -
    -    size_t hash_value() const;
    -
    -    xml_attribute next_attribute() const;
    -    xml_attribute previous_attribute() const;
    -
    -    const char_t* name() const;
    -    const char_t* value() const;
    -
    -    const char_t* as_string(const char_t* def = "") const;
    -    int as_int(int def = 0) const;
    -    unsigned int as_uint(unsigned int def = 0) const;
    -    double as_double(double def = 0) const;
    -    float as_float(float def = 0) const;
    -    bool as_bool(bool def = false) const;
    -    long long as_llong(long long def = 0) const;
    -    unsigned long long as_ullong(unsigned long long def = 0) const;
    -
    -    bool set_name(const char_t* rhs);
    -    bool set_value(const char_t* rhs);
    -    bool set_value(int rhs);
    -    bool set_value(unsigned int rhs);
    -    bool set_value(long rhs);
    -    bool set_value(unsigned long rhs);
    -    bool set_value(double rhs);
    -    bool set_value(float rhs);
    -    bool set_value(bool rhs);
    -    bool set_value(long long rhs);
    -    bool set_value(unsigned long long rhs);
    -
    -    xml_attribute& operator=(const char_t* rhs);
    -    xml_attribute& operator=(int rhs);
    -    xml_attribute& operator=(unsigned int rhs);
    -    xml_attribute& operator=(long rhs);
    -    xml_attribute& operator=(unsigned long rhs);
    -    xml_attribute& operator=(double rhs);
    -    xml_attribute& operator=(float rhs);
    -    xml_attribute& operator=(bool rhs);
    -    xml_attribute& operator=(long long rhs);
    -    xml_attribute& operator=(unsnigned long long rhs);
    -
    -class xml_node
    -    xml_node();
    -
    -    bool empty() const;
    -    operator unspecified_bool_type() const;
    -
    -    bool operator==(const xml_node& r) const;
    -    bool operator!=(const xml_node& r) const;
    -    bool operator<(const xml_node& r) const;
    -    bool operator>(const xml_node& r) const;
    -    bool operator<=(const xml_node& r) const;
    -    bool operator>=(const xml_node& r) const;
    -
    -    size_t hash_value() const;
    -
    -    xml_node_type type() const;
    -
    -    const char_t* name() const;
    -    const char_t* value() const;
    -
    -    xml_node parent() const;
    -    xml_node first_child() const;
    -    xml_node last_child() const;
    -    xml_node next_sibling() const;
    -    xml_node previous_sibling() const;
    -
    -    xml_attribute first_attribute() const;
    -    xml_attribute last_attribute() const;
    -
    -    implementation-defined-type children() const;
    -    implementation-defined-type children(const char_t* name) const;
    -    implementation-defined-type attributes() const;
    -
    -    xml_node child(const char_t* name) const;
    -    xml_attribute attribute(const char_t* name) const;
    -    xml_node next_sibling(const char_t* name) const;
    -    xml_node previous_sibling(const char_t* name) const;
    -    xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
    -    xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const;
    -
    -    const char_t* child_value() const;
    -    const char_t* child_value(const char_t* name) const;
    -    xml_text text() const;
    -
    -    typedef xml_node_iterator iterator;
    -    iterator begin() const;
    -    iterator end() const;
    -
    -    typedef xml_attribute_iterator attribute_iterator;
    -    attribute_iterator attributes_begin() const;
    -    attribute_iterator attributes_end() const;
    -
    -    bool traverse(xml_tree_walker& walker);
    -
    -    template <typename Predicate> xml_attribute find_attribute(Predicate pred) const;
    -    template <typename Predicate> xml_node find_child(Predicate pred) const;
    -    template <typename Predicate> xml_node find_node(Predicate pred) const;
    -
    -    string_t path(char_t delimiter = '/') const;
    -    xml_node xml_node::first_element_by_path(const char_t* path, char_t delimiter = '/') const;
    -    xml_node root() const;
    -    ptrdiff_t offset_debug() const;
    -
    -    bool set_name(const char_t* rhs);
    -    bool set_value(const char_t* rhs);
    -
    -    xml_attribute append_attribute(const char_t* name);
    -    xml_attribute prepend_attribute(const char_t* name);
    -    xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr);
    -    xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr);
    -
    -    xml_node append_child(xml_node_type type = node_element);
    -    xml_node prepend_child(xml_node_type type = node_element);
    -    xml_node insert_child_after(xml_node_type type, const xml_node& node);
    -    xml_node insert_child_before(xml_node_type type, const xml_node& node);
    -
    -    xml_node append_child(const char_t* name);
    -    xml_node prepend_child(const char_t* name);
    -    xml_node insert_child_after(const char_t* name, const xml_node& node);
    -    xml_node insert_child_before(const char_t* name, const xml_node& node);
    -
    -    xml_attribute append_copy(const xml_attribute& proto);
    -    xml_attribute prepend_copy(const xml_attribute& proto);
    -    xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr);
    -    xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr);
    -
    -    xml_node append_copy(const xml_node& proto);
    -    xml_node prepend_copy(const xml_node& proto);
    -    xml_node insert_copy_after(const xml_node& proto, const xml_node& node);
    -    xml_node insert_copy_before(const xml_node& proto, const xml_node& node);
    -
    -    xml_node append_move(const xml_node& moved);
    -    xml_node prepend_move(const xml_node& moved);
    -    xml_node insert_move_after(const xml_node& moved, const xml_node& node);
    -    xml_node insert_move_before(const xml_node& moved, const xml_node& node);
    -
    -    bool remove_attribute(const xml_attribute& a);
    -    bool remove_attribute(const char_t* name);
    -    bool remove_attributes();
    -    bool remove_child(const xml_node& n);
    -    bool remove_child(const char_t* name);
    -    bool remove_children();
    -
    -    xml_parse_result append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    -
    -    void print(xml_writer& writer, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
    -    void print(std::ostream& os, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
    -    void print(std::wostream& os, const char_t* indent = "\t", unsigned int flags = format_default, unsigned int depth = 0) const;
    -
    -    xpath_node select_node(const char_t* query, xpath_variable_set* variables = 0) const;
    -    xpath_node select_node(const xpath_query& query) const;
    -    xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const;
    -    xpath_node_set select_nodes(const xpath_query& query) const;
    -
    -class xml_document
    -    xml_document();
    -    ~xml_document();
    -
    -    void reset();
    -    void reset(const xml_document& proto);
    -
    -    xml_parse_result load(std::istream& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    -    xml_parse_result load(std::wistream& stream, unsigned int options = parse_default);
    -
    -    xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default);
    -
    -    xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    -    xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    -
    -    xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    -    xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    -    xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    +
    class xml_attribute
    +    xml_attribute();
    +
    +    bool empty() const;
    +    operator unspecified_bool_type() const;
    +
    +    bool operator==(const xml_attribute& r) const;
    +    bool operator!=(const xml_attribute& r) const;
    +    bool operator<(const xml_attribute& r) const;
    +    bool operator>(const xml_attribute& r) const;
    +    bool operator<=(const xml_attribute& r) const;
    +    bool operator>=(const xml_attribute& r) const;
    +
    +    size_t hash_value() const;
    +
    +    xml_attribute next_attribute() const;
    +    xml_attribute previous_attribute() const;
    +
    +    const char_t* name() const;
    +    const char_t* value() const;
    +
    +    const char_t* as_string(const char_t* def = "") const;
    +    int as_int(int def = 0) const;
    +    unsigned int as_uint(unsigned int def = 0) const;
    +    double as_double(double def = 0) const;
    +    float as_float(float def = 0) const;
    +    bool as_bool(bool def = false) const;
    +    long long as_llong(long long def = 0) const;
    +    unsigned long long as_ullong(unsigned long long def = 0) const;
    +
    +    bool set_name(const char_t* rhs);
    +    bool set_value(const char_t* rhs);
    +    bool set_value(int rhs);
    +    bool set_value(unsigned int rhs);
    +    bool set_value(long rhs);
    +    bool set_value(unsigned long rhs);
    +    bool set_value(double rhs);
    +    bool set_value(float rhs);
    +    bool set_value(bool rhs);
    +    bool set_value(long long rhs);
    +    bool set_value(unsigned long long rhs);
    +
    +    xml_attribute& operator=(const char_t* rhs);
    +    xml_attribute& operator=(int rhs);
    +    xml_attribute& operator=(unsigned int rhs);
    +    xml_attribute& operator=(long rhs);
    +    xml_attribute& operator=(unsigned long rhs);
    +    xml_attribute& operator=(double rhs);
    +    xml_attribute& operator=(float rhs);
    +    xml_attribute& operator=(bool rhs);
    +    xml_attribute& operator=(long long rhs);
    +    xml_attribute& operator=(unsnigned long long rhs);
    +
    +class xml_node
    +    xml_node();
    +
    +    bool empty() const;
    +    operator unspecified_bool_type() const;
    +
    +    bool operator==(const xml_node& r) const;
    +    bool operator!=(const xml_node& r) const;
    +    bool operator<(const xml_node& r) const;
    +    bool operator>(const xml_node& r) const;
    +    bool operator<=(const xml_node& r) const;
    +    bool operator>=(const xml_node& r) const;
    +
    +    size_t hash_value() const;
    +
    +    xml_node_type type() const;
    +
    +    const char_t* name() const;
    +    const char_t* value() const;
    +
    +    xml_node parent() const;
    +    xml_node first_child() const;
    +    xml_node last_child() const;
    +    xml_node next_sibling() const;
    +    xml_node previous_sibling() const;
    +
    +    xml_attribute first_attribute() const;
    +    xml_attribute last_attribute() const;
    +
    +    implementation-defined-type children() const;
    +    implementation-defined-type children(const char_t* name) const;
    +    implementation-defined-type attributes() const;
    +
    +    xml_node child(const char_t* name) const;
    +    xml_attribute attribute(const char_t* name) const;
    +    xml_node next_sibling(const char_t* name) const;
    +    xml_node previous_sibling(const char_t* name) const;
    +    xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
    +    xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const;
    +
    +    const char_t* child_value() const;
    +    const char_t* child_value(const char_t* name) const;
    +    xml_text text() const;
    +
    +    typedef xml_node_iterator iterator;
    +    iterator begin() const;
    +    iterator end() const;
    +
    +    typedef xml_attribute_iterator attribute_iterator;
    +    attribute_iterator attributes_begin() const;
    +    attribute_iterator attributes_end() const;
    +
    +    bool traverse(xml_tree_walker& walker);
    +
    +    template <typename Predicate> xml_attribute find_attribute(Predicate pred) const;
    +    template <typename Predicate> xml_node find_child(Predicate pred) const;
    +    template <typename Predicate> xml_node find_node(Predicate pred) const;
    +
    +    string_t path(char_t delimiter = '/') const;
    +    xml_node xml_node::first_element_by_path(const char_t* path, char_t delimiter = '/') const;
    +    xml_node root() const;
    +    ptrdiff_t offset_debug() const;
    +
    +    bool set_name(const char_t* rhs);
    +    bool set_value(const char_t* rhs);
    +
    +    xml_attribute append_attribute(const char_t* name);
    +    xml_attribute prepend_attribute(const char_t* name);
    +    xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr);
    +    xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr);
    +
    +    xml_node append_child(xml_node_type type = node_element);
    +    xml_node prepend_child(xml_node_type type = node_element);
    +    xml_node insert_child_after(xml_node_type type, const xml_node& node);
    +    xml_node insert_child_before(xml_node_type type, const xml_node& node);
    +
    +    xml_node append_child(const char_t* name);
    +    xml_node prepend_child(const char_t* name);
    +    xml_node insert_child_after(const char_t* name, const xml_node& node);
    +    xml_node insert_child_before(const char_t* name, const xml_node& node);
    +
    +    xml_attribute append_copy(const xml_attribute& proto);
    +    xml_attribute prepend_copy(const xml_attribute& proto);
    +    xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr);
    +    xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr);
    +
    +    xml_node append_copy(const xml_node& proto);
    +    xml_node prepend_copy(const xml_node& proto);
    +    xml_node insert_copy_after(const xml_node& proto, const xml_node& node);
    +    xml_node insert_copy_before(const xml_node& proto, const xml_node& node);
    +
    +    xml_node append_move(const xml_node& moved);
    +    xml_node prepend_move(const xml_node& moved);
    +    xml_node insert_move_after(const xml_node& moved, const xml_node& node);
    +    xml_node insert_move_before(const xml_node& moved, const xml_node& node);
    +
    +    bool remove_attribute(const xml_attribute& a);
    +    bool remove_attribute(const char_t* name);
    +    bool remove_attributes();
    +    bool remove_child(const xml_node& n);
    +    bool remove_child(const char_t* name);
    +    bool remove_children();
    +
    +    xml_parse_result append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    +
    +    void print(xml_writer& writer, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
    +    void print(std::ostream& os, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
    +    void print(std::wostream& os, const char_t* indent = "\t", unsigned int flags = format_default, unsigned int depth = 0) const;
    +
    +    xpath_node select_node(const char_t* query, xpath_variable_set* variables = 0) const;
    +    xpath_node select_node(const xpath_query& query) const;
    +    xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const;
    +    xpath_node_set select_nodes(const xpath_query& query) const;
    +
    +class xml_document
    +    xml_document();
    +    ~xml_document();
    +
    +    void reset();
    +    void reset(const xml_document& proto);
    +
    +    xml_parse_result load(std::istream& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    +    xml_parse_result load(std::wistream& stream, unsigned int options = parse_default);
    +
    +    xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default);
    +
    +    xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    +    xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    +
    +    xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    +    xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
    +    xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
     
    -    bool save_file(const char* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
    -    bool save_file(const wchar_t* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
    +    bool save_file(const char* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
    +    bool save_file(const wchar_t* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
     
    -    void save(std::ostream& stream, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
    -    void save(std::wostream& stream, const char_t* indent = "\t", unsigned int flags = format_default) const;
    +    void save(std::ostream& stream, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
    +    void save(std::wostream& stream, const char_t* indent = "\t", unsigned int flags = format_default) const;
     
    -    void save(xml_writer& writer, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
    +    void save(xml_writer& writer, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
     
    -    xml_node document_element() const;
    +    xml_node document_element() const;
     
    -struct xml_parse_result
    -    xml_parse_status status;
    -    ptrdiff_t offset;
    -    xml_encoding encoding;
    +struct xml_parse_result
    +    xml_parse_status status;
    +    ptrdiff_t offset;
    +    xml_encoding encoding;
     
    -    operator bool() const;
    -    const char* description() const;
    +    operator bool() const;
    +    const char* description() const;
     
    -class xml_node_iterator
    -class xml_attribute_iterator
    +class xml_node_iterator
    +class xml_attribute_iterator
     
    -class xml_tree_walker
    -    virtual bool begin(xml_node& node);
    -    virtual bool for_each(xml_node& node) = 0;
    -    virtual bool end(xml_node& node);
    +class xml_tree_walker
    +    virtual bool begin(xml_node& node);
    +    virtual bool for_each(xml_node& node) = 0;
    +    virtual bool end(xml_node& node);
     
    -    int depth() const;
    +    int depth() const;
     
    -class xml_text
    -    bool empty() const;
    -    operator xml_text::unspecified_bool_type() const;
    +class xml_text
    +    bool empty() const;
    +    operator xml_text::unspecified_bool_type() const;
     
    -    const char_t* xml_text::get() const;
    +    const char_t* xml_text::get() const;
     
    -    const char_t* as_string(const char_t* def = "") const;
    -    int as_int(int def = 0) const;
    -    unsigned int as_uint(unsigned int def = 0) const;
    -    double as_double(double def = 0) const;
    -    float as_float(float def = 0) const;
    -    bool as_bool(bool def = false) const;
    -    long long as_llong(long long def = 0) const;
    -    unsigned long long as_ullong(unsigned long long def = 0) const;
    +    const char_t* as_string(const char_t* def = "") const;
    +    int as_int(int def = 0) const;
    +    unsigned int as_uint(unsigned int def = 0) const;
    +    double as_double(double def = 0) const;
    +    float as_float(float def = 0) const;
    +    bool as_bool(bool def = false) const;
    +    long long as_llong(long long def = 0) const;
    +    unsigned long long as_ullong(unsigned long long def = 0) const;
     
    -    bool set(const char_t* rhs);
    +    bool set(const char_t* rhs);
     
    -    bool set(int rhs);
    -    bool set(unsigned int rhs);
    -    bool set(long rhs);
    -    bool set(unsigned long rhs);
    -    bool set(double rhs);
    -    bool set(float rhs);
    -    bool set(bool rhs);
    -    bool set(long long rhs);
    -    bool set(unsigned long long rhs);
    +    bool set(int rhs);
    +    bool set(unsigned int rhs);
    +    bool set(long rhs);
    +    bool set(unsigned long rhs);
    +    bool set(double rhs);
    +    bool set(float rhs);
    +    bool set(bool rhs);
    +    bool set(long long rhs);
    +    bool set(unsigned long long rhs);
     
    -    xml_text& operator=(const char_t* rhs);
    -    xml_text& operator=(int rhs);
    -    xml_text& operator=(unsigned int rhs);
    -    xml_text& operator=(long rhs);
    -    xml_text& operator=(unsigned long rhs);
    -    xml_text& operator=(double rhs);
    -    xml_text& operator=(float rhs);
    -    xml_text& operator=(bool rhs);
    -    xml_text& operator=(long long rhs);
    -    xml_text& operator=(unsigned long long rhs);
    +    xml_text& operator=(const char_t* rhs);
    +    xml_text& operator=(int rhs);
    +    xml_text& operator=(unsigned int rhs);
    +    xml_text& operator=(long rhs);
    +    xml_text& operator=(unsigned long rhs);
    +    xml_text& operator=(double rhs);
    +    xml_text& operator=(float rhs);
    +    xml_text& operator=(bool rhs);
    +    xml_text& operator=(long long rhs);
    +    xml_text& operator=(unsigned long long rhs);
     
    -    xml_node data() const;
    +    xml_node data() const;
     
    -class xml_writer
    -    virtual void write(const void* data, size_t size) = 0;
    +class xml_writer
    +    virtual void write(const void* data, size_t size) = 0;
     
    -class xml_writer_file: public xml_writer
    -    xml_writer_file(void* file);
    +class xml_writer_file: public xml_writer
    +    xml_writer_file(void* file);
     
    -class xml_writer_stream: public xml_writer
    -    xml_writer_stream(std::ostream& stream);
    -    xml_writer_stream(std::wostream& stream);
    +class xml_writer_stream: public xml_writer
    +    xml_writer_stream(std::ostream& stream);
    +    xml_writer_stream(std::wostream& stream);
     
    -struct xpath_parse_result
    -    const char* error;
    -    ptrdiff_t offset;
    +struct xpath_parse_result
    +    const char* error;
    +    ptrdiff_t offset;
     
    -    operator bool() const;
    -    const char* description() const;
    +    operator bool() const;
    +    const char* description() const;
     
    -class xpath_query
    -    explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0);
    +class xpath_query
    +    explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0);
     
    -    bool evaluate_boolean(const xpath_node& n) const;
    -    double evaluate_number(const xpath_node& n) const;
    -    string_t evaluate_string(const xpath_node& n) const;
    -    size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const;
    -    xpath_node_set evaluate_node_set(const xpath_node& n) const;
    -    xpath_node evaluate_node(const xpath_node& n) const;
    +    bool evaluate_boolean(const xpath_node& n) const;
    +    double evaluate_number(const xpath_node& n) const;
    +    string_t evaluate_string(const xpath_node& n) const;
    +    size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const;
    +    xpath_node_set evaluate_node_set(const xpath_node& n) const;
    +    xpath_node evaluate_node(const xpath_node& n) const;
     
    -    xpath_value_type return_type() const;
    +    xpath_value_type return_type() const;
     
    -    const xpath_parse_result& result() const;
    -    operator unspecified_bool_type() const;
    +    const xpath_parse_result& result() const;
    +    operator unspecified_bool_type() const;
     
    -class xpath_exception: public std::exception
    -    virtual const char* what() const throw();
    +class xpath_exception: public std::exception
    +    virtual const char* what() const throw();
     
    -    const xpath_parse_result& result() const;
    +    const xpath_parse_result& result() const;
     
    -class xpath_node
    -    xpath_node();
    -    xpath_node(const xml_node& node);
    -    xpath_node(const xml_attribute& attribute, const xml_node& parent);
    +class xpath_node
    +    xpath_node();
    +    xpath_node(const xml_node& node);
    +    xpath_node(const xml_attribute& attribute, const xml_node& parent);
     
    -    xml_node node() const;
    -    xml_attribute attribute() const;
    -    xml_node parent() const;
    +    xml_node node() const;
    +    xml_attribute attribute() const;
    +    xml_node parent() const;
     
    -    operator unspecified_bool_type() const;
    -    bool operator==(const xpath_node& n) const;
    -    bool operator!=(const xpath_node& n) const;
    +    operator unspecified_bool_type() const;
    +    bool operator==(const xpath_node& n) const;
    +    bool operator!=(const xpath_node& n) const;
     
    -class xpath_node_set
    -    xpath_node_set();
    -    xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted);
    -
    -    typedef const xpath_node* const_iterator;
    -    const_iterator begin() const;
    -    const_iterator end() const;
    +class xpath_node_set
    +    xpath_node_set();
    +    xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted);
    +
    +    typedef const xpath_node* const_iterator;
    +    const_iterator begin() const;
    +    const_iterator end() const;
     
    -    const xpath_node& operator[](size_t index) const;
    -    size_t size() const;
    -    bool empty() const;
    -
    -    xpath_node first() const;
    -
    -    enum type_t {type_unsorted, type_sorted, type_sorted_reverse};
    -    type_t type() const;
    -    void sort(bool reverse = false);
    -
    -class xpath_variable
    -    const char_t* name() const;
    -    xpath_value_type type() const;
    -
    -    bool get_boolean() const;
    -    double get_number() const;
    -    const char_t* get_string() const;
    -    const xpath_node_set& get_node_set() const;
    -
    -    bool set(bool value);
    -    bool set(double value);
    -    bool set(const char_t* value);
    -    bool set(const xpath_node_set& value);
    +    const xpath_node& operator[](size_t index) const;
    +    size_t size() const;
    +    bool empty() const;
    +
    +    xpath_node first() const;
    +
    +    enum type_t {type_unsorted, type_sorted, type_sorted_reverse};
    +    type_t type() const;
    +    void sort(bool reverse = false);
    +
    +class xpath_variable
    +    const char_t* name() const;
    +    xpath_value_type type() const;
    +
    +    bool get_boolean() const;
    +    double get_number() const;
    +    const char_t* get_string() const;
    +    const xpath_node_set& get_node_set() const;
    +
    +    bool set(bool value);
    +    bool set(double value);
    +    bool set(const char_t* value);
    +    bool set(const xpath_node_set& value);
     
    -class xpath_variable_set
    -    xpath_variable* add(const char_t* name, xpath_value_type type);
    +class xpath_variable_set
    +    xpath_variable* add(const char_t* name, xpath_value_type type);
     
    -    bool set(const char_t* name, bool value);
    -    bool set(const char_t* name, double value);
    -    bool set(const char_t* name, const char_t* value);
    -    bool set(const char_t* name, const xpath_node_set& value);
    +    bool set(const char_t* name, bool value);
    +    bool set(const char_t* name, double value);
    +    bool set(const char_t* name, const char_t* value);
    +    bool set(const char_t* name, const xpath_node_set& value);
     
    -    xpath_variable* get(const char_t* name);
    -    const xpath_variable* get(const char_t* name) const;
    + xpath_variable* get(const char_t* name); + const xpath_variable* get(const char_t* name) const;
    @@ -5840,13 +5984,13 @@ If exceptions are disabled, then in the event of parsing failure the query is in

    10.6. Functions

    -
    std::string as_utf8(const wchar_t* str);
    -std::string as_utf8(const std::wstring& str);
    -std::wstring as_wide(const char* str);
    -std::wstring as_wide(const std::string& str);
    -void set_memory_management_functions(allocation_function allocate, deallocation_function deallocate);
    -allocation_function get_memory_allocation_function();
    -deallocation_function get_memory_deallocation_function();
    +
    std::string as_utf8(const wchar_t* str);
    +std::string as_utf8(const std::wstring& str);
    +std::wstring as_wide(const char* str);
    +std::wstring as_wide(const std::string& str);
    +void set_memory_management_functions(allocation_function allocate, deallocation_function deallocate);
    +allocation_function get_memory_allocation_function();
    +deallocation_function get_memory_deallocation_function();
    @@ -5861,79 +6005,8 @@ If exceptions are disabled, then in the event of parsing failure the query is in - \ No newline at end of file diff --git a/docs/quickstart.adoc b/docs/quickstart.adoc index ee15665..d9fb69e 100644 --- a/docs/quickstart.adoc +++ b/docs/quickstart.adoc @@ -255,7 +255,7 @@ If filing an issue is not possible due to privacy or other concerns, you can con The pugixml library is distributed under the MIT license: .... -Copyright (c) 2006-2020 Arseny Kapoulkine +Copyright (c) 2006-2022 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -283,5 +283,5 @@ This means that you can freely use pugixml in your applications, both open-sourc .... This software is based on pugixml library (https://pugixml.org). -pugixml is Copyright (C) 2006-2020 Arseny Kapoulkine. +pugixml is Copyright (C) 2006-2022 Arseny Kapoulkine. .... diff --git a/docs/quickstart.html b/docs/quickstart.html index 57e6a98..2c8a1ab 100644 --- a/docs/quickstart.html +++ b/docs/quickstart.html @@ -4,26 +4,24 @@ - + -pugixml 1.11 quick start guide +pugixml 1.12 quick start guide + @@ -677,13 +748,13 @@ All pugixml classes and functions are located in pugi namespace; yo
    -
    for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
    -{
    -    std::cout << "Tool " << tool.attribute("Filename").value();
    -    std::cout << ": AllowRemote " << tool.attribute("AllowRemote").as_bool();
    -    std::cout << ", Timeout " << tool.attribute("Timeout").as_int();
    -    std::cout << ", Description '" << tool.child_value("Description") << "'\n";
    -}
    +
    for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
    +{
    +    std::cout << "Tool " << tool.attribute("Filename").value();
    +    std::cout << ": AllowRemote " << tool.attribute("AllowRemote").as_bool();
    +    std::cout << ", Timeout " << tool.attribute("Timeout").as_int();
    +    std::cout << ", Description '" << tool.child_value("Description") << "'\n";
    +}
    @@ -691,12 +762,12 @@ All pugixml classes and functions are located in pugi namespace; yo
    -
    std::cout << "Tool for *.dae generation: " << tools.find_child_by_attribute("Tool", "OutputFileMasks", "*.dae").attribute("Filename").value() << "\n";
    +
    std::cout << "Tool for *.dae generation: " << tools.find_child_by_attribute("Tool", "OutputFileMasks", "*.dae").attribute("Filename").value() << "\n";
     
    -for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
    -{
    -    std::cout << "Tool " << tool.attribute("Filename").value() << "\n";
    -}
    +for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool")) +{ + std::cout << "Tool " << tool.attribute("Filename").value() << "\n"; +}
    @@ -707,17 +778,17 @@ All pugixml classes and functions are located in pugi namespace; yo
    -
    for (pugi::xml_node_iterator it = tools.begin(); it != tools.end(); ++it)
    -{
    -    std::cout << "Tool:";
    +
    for (pugi::xml_node_iterator it = tools.begin(); it != tools.end(); ++it)
    +{
    +    std::cout << "Tool:";
     
    -    for (pugi::xml_attribute_iterator ait = it->attributes_begin(); ait != it->attributes_end(); ++ait)
    -    {
    -        std::cout << " " << ait->name() << "=" << ait->value();
    -    }
    +    for (pugi::xml_attribute_iterator ait = it->attributes_begin(); ait != it->attributes_end(); ++ait)
    +    {
    +        std::cout << " " << ait->name() << "=" << ait->value();
    +    }
     
    -    std::cout << std::endl;
    -}
    + std::cout << std::endl; +}
    @@ -728,22 +799,22 @@ All pugixml classes and functions are located in pugi namespace; yo
    -
    for (pugi::xml_node tool: tools.children("Tool"))
    -{
    -    std::cout << "Tool:";
    +
    for (pugi::xml_node tool: tools.children("Tool"))
    +{
    +    std::cout << "Tool:";
     
    -    for (pugi::xml_attribute attr: tool.attributes())
    -    {
    -        std::cout << " " << attr.name() << "=" << attr.value();
    -    }
    +    for (pugi::xml_attribute attr: tool.attributes())
    +    {
    +        std::cout << " " << attr.name() << "=" << attr.value();
    +    }
     
    -    for (pugi::xml_node child: tool.children())
    -    {
    -        std::cout << ", child " << child.name();
    -    }
    +    for (pugi::xml_node child: tool.children())
    +    {
    +        std::cout << ", child " << child.name();
    +    }
     
    -    std::cout << std::endl;
    -}
    + std::cout << std::endl; +}
    @@ -754,23 +825,23 @@ All pugixml classes and functions are located in pugi namespace; yo
    -
    struct simple_walker: pugi::xml_tree_walker
    -{
    -    virtual bool for_each(pugi::xml_node& node)
    -    {
    -        for (int i = 0; i < depth(); ++i) std::cout << "  "; // indentation
    +
    struct simple_walker: pugi::xml_tree_walker
    +{
    +    virtual bool for_each(pugi::xml_node& node)
    +    {
    +        for (int i = 0; i < depth(); ++i) std::cout << "  "; // indentation
     
    -        std::cout << node_types[node.type()] << ": name='" << node.name() << "', value='" << node.value() << "'\n";
    +        std::cout << node_types[node.type()] << ": name='" << node.name() << "', value='" << node.value() << "'\n";
     
    -        return true; // continue traversal
    -    }
    -};
    + return true; // continue traversal + } +};
    -
    simple_walker walker;
    -doc.traverse(walker);
    +
    simple_walker walker;
    +doc.traverse(walker);
    @@ -778,20 +849,20 @@ All pugixml classes and functions are located in pugi namespace; yo
    -
    pugi::xpath_node_set tools = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']");
    +
    pugi::xpath_node_set tools = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']");
     
    -std::cout << "Tools:\n";
    +std::cout << "Tools:\n";
     
    -for (pugi::xpath_node_set::const_iterator it = tools.begin(); it != tools.end(); ++it)
    -{
    -    pugi::xpath_node node = *it;
    -    std::cout << node.node().attribute("Filename").value() << "\n";
    -}
    +for (pugi::xpath_node_set::const_iterator it = tools.begin(); it != tools.end(); ++it)
    +{
    +    pugi::xpath_node node = *it;
    +    std::cout << node.node().attribute("Filename").value() << "\n";
    +}
     
    -pugi::xpath_node build_tool = doc.select_node("//Tool[contains(Description, 'build system')]");
    +pugi::xpath_node build_tool = doc.select_node("//Tool[contains(Description, 'build system')]");
     
    -if (build_tool)
    -    std::cout << "Build tool: " << build_tool.node().attribute("Filename").value() << "\n";
    +if (build_tool) + std::cout << "Build tool: " << build_tool.node().attribute("Filename").value() << "\n";
    @@ -822,35 +893,35 @@ XPath functions throw xpath_exception objects on error; the sample
    -
    pugi::xml_node node = doc.child("node");
    +
    pugi::xml_node node = doc.child("node");
     
     // change node name
    -std::cout << node.set_name("notnode");
    -std::cout << ", new node name: " << node.name() << std::endl;
    +std::cout << node.set_name("notnode");
    +std::cout << ", new node name: " << node.name() << std::endl;
     
     // change comment text
    -std::cout << doc.last_child().set_value("useless comment");
    -std::cout << ", new comment text: " << doc.last_child().value() << std::endl;
    +std::cout << doc.last_child().set_value("useless comment");
    +std::cout << ", new comment text: " << doc.last_child().value() << std::endl;
     
     // we can't change value of the element or name of the comment
    -std::cout << node.set_value("1") << ", " << doc.last_child().set_name("2") << std::endl;
    +std::cout << node.set_value("1") << ", " << doc.last_child().set_name("2") << std::endl;
    -
    pugi::xml_attribute attr = node.attribute("id");
    +
    pugi::xml_attribute attr = node.attribute("id");
     
     // change attribute name/value
    -std::cout << attr.set_name("key") << ", " << attr.set_value("345");
    -std::cout << ", new attribute: " << attr.name() << "=" << attr.value() << std::endl;
    +std::cout << attr.set_name("key") << ", " << attr.set_value("345");
    +std::cout << ", new attribute: " << attr.name() << "=" << attr.value() << std::endl;
     
     // we can use numbers or booleans
    -attr.set_value(1.234);
    -std::cout << "new attribute value: " << attr.value() << std::endl;
    +attr.set_value(1.234);
    +std::cout << "new attribute value: " << attr.value() << std::endl;
     
     // we can also use assignment operators for more concise code
    -attr = true;
    -std::cout << "final attribute value: " << attr.value() << std::endl;
    +attr = true; +std::cout << "final attribute value: " << attr.value() << std::endl;
    @@ -874,19 +945,19 @@ XPath functions throw xpath_exception objects on error; the sample
    // add node with some name
    -pugi::xml_node node = doc.append_child("node");
    +pugi::xml_node node = doc.append_child("node");
     
     // add description node with text child
    -pugi::xml_node descr = node.append_child("description");
    -descr.append_child(pugi::node_pcdata).set_value("Simple node");
    +pugi::xml_node descr = node.append_child("description");
    +descr.append_child(pugi::node_pcdata).set_value("Simple node");
     
     // add param node before the description
    -pugi::xml_node param = node.insert_child_before("param", descr);
    +pugi::xml_node param = node.insert_child_before("param", descr);
     
     // add attributes to param node
    -param.append_attribute("name") = "version";
    -param.append_attribute("value") = 1.1;
    -param.insert_attribute_after("type", param.attribute("name")) = "float";
    +param.append_attribute("name") = "version"; +param.append_attribute("value") = 1.1; +param.insert_attribute_after("type", param.attribute("name")) = "float";
    @@ -898,16 +969,16 @@ XPath functions throw xpath_exception objects on error; the sample
    // remove description node with the whole subtree
    -pugi::xml_node node = doc.child("node");
    -node.remove_child("description");
    +pugi::xml_node node = doc.child("node");
    +node.remove_child("description");
     
     // remove id attribute
    -pugi::xml_node param = node.child("param");
    -param.remove_attribute("value");
    +pugi::xml_node param = node.child("param");
    +param.remove_attribute("value");
     
     // we can also remove nodes/attributes by handles
    -pugi::xml_attribute id = param.attribute("name");
    -param.remove_attribute(id);
    +pugi::xml_attribute id = param.attribute("name"); +param.remove_attribute(id);
    @@ -927,7 +998,7 @@ XPath functions throw xpath_exception objects on error; the sample
    // save document to file
    -std::cout << "Saving result: " << doc.save_file("save_file_output.xml") << std::endl;
    +std::cout << "Saving result: " << doc.save_file("save_file_output.xml") << std::endl;
    @@ -939,8 +1010,8 @@ XPath functions throw xpath_exception objects on error; the sample
    // save document to standard output
    -std::cout << "Document:\n";
    -doc.save(std::cout);
    +std::cout << "Document:\n"; +doc.save(std::cout);
    @@ -951,15 +1022,15 @@ XPath functions throw xpath_exception objects on error; the sample
    -
    struct xml_string_writer: pugi::xml_writer
    -{
    -    std::string result;
    +
    struct xml_string_writer: pugi::xml_writer
    +{
    +    std::string result;
     
    -    virtual void write(const void* data, size_t size)
    -    {
    -        result.append(static_cast<const char*>(data), size);
    -    }
    -};
    + virtual void write(const void* data, size_t size) + { + result.append(static_cast<const char*>(data), size); + } +};
    @@ -986,7 +1057,7 @@ XPath functions throw xpath_exception objects on error; the sample
    -
    Copyright (c) 2006-2020 Arseny Kapoulkine
    +
    Copyright (c) 2006-2022 Arseny Kapoulkine
     
     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation
    @@ -1016,7 +1087,7 @@ OTHER DEALINGS IN THE SOFTWARE.
    This software is based on pugixml library (https://pugixml.org).
    -pugixml is Copyright (C) 2006-2020 Arseny Kapoulkine.
    +pugixml is Copyright (C) 2006-2022 Arseny Kapoulkine.
    @@ -1030,79 +1101,8 @@ pugixml is Copyright (C) 2006-2020 Arseny Kapoulkine.
    - \ No newline at end of file