pugixml stores XML data in DOM-like way: the entire XML document (both document
structure and element data) is stored in memory as a tree. The tree can be
loaded from character stream (file, string, C++ I/O stream), then traversed
via special API or XPath expressions. The whole tree is mutable: both node
structure and node/attribute data can be changed at any time. Finally, the
result of document transformations can be saved to a character stream (file,
C++ I/O stream or custom transport).
</p>
<divclass="section">
<divclass="titlepage"><div><div><h3class="title">
<aname="manual.dom.tree"></a><aclass="link"href="dom.html#manual.dom.tree"title="Tree structure"> Tree structure</a>
</h3></div></div></div>
<p>
The XML document is represented with a tree data structure. The root of the
tree is the document itself, which corresponds to C++ type <codeclass="computeroutput"><spanclass="identifier">xml_document</span></code>. Document has one or more
child nodes, which correspond to C++ type <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>.
Nodes have different types; depending on a type, a node can have a collection
of child nodes, a collection of attributes, which correspond to C++ type
<codeclass="computeroutput"><spanclass="identifier">xml_attribute</span></code>, and some additional
data (i.e. name).
</p>
<aname="xml_node_type"></a><p>
The tree nodes can be of one of the following types (which together form
the enumeration <codeclass="computeroutput"><spanclass="identifier">xml_node_type</span></code>):
Here <codeclass="computeroutput"><spanclass="string">"node"</span></code> element
has three children, two of which are PCDATA nodes with values <codeclass="computeroutput"><spanclass="string">"text1"</span></code> and <codeclass="computeroutput"><spanclass="string">"text2"</span></code>.
All pugixml classes and functions are located in <codeclass="computeroutput"><spanclass="identifier">pugi</span></code>
namespace; you have to either use explicit name qualification (i.e. <codeclass="computeroutput"><spanclass="identifier">pugi</span><spanclass="special">::</span><spanclass="identifier">xml_node</span></code>), or to gain access to relevant
symbols via <codeclass="computeroutput"><spanclass="keyword">using</span></code> directive
(i.e. <codeclass="computeroutput"><spanclass="keyword">using</span><spanclass="identifier">pugi</span><spanclass="special">::</span><spanclass="identifier">xml_node</span><spanclass="special">;</span></code> or <codeclass="computeroutput"><spanclass="keyword">using</span>
<spanclass="keyword">namespace</span><spanclass="identifier">pugi</span><spanclass="special">;</span></code>). The namespace will be omitted from declarations
in this documentation hereafter; all code examples will use fully-qualified
names.
</p></td></tr>
</table></div>
<p>
Despite the fact that there are several node types, there are only three
C++ types representing the tree (<codeclass="computeroutput"><spanclass="identifier">xml_document</span></code>,
some operations on <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>
are only valid for certain node types. They are described below.
</p>
<aname="xml_document"></a><p>
<codeclass="computeroutput"><spanclass="identifier">xml_document</span></code> is the owner
of the entire document structure; it is a non-copyable class. The interface
of <codeclass="computeroutput"><spanclass="identifier">xml_document</span></code> consists
of loading functions (see <aclass="xref"href="loading.html"title="Loading document"> Loading document</a>), saving functions (see <aclass="xref"href="saving.html"title="Saving document"> Saving document</a>)
and the interface of <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>,
which allows for document inspection and/or modification. Note that while
<codeclass="computeroutput"><spanclass="identifier">xml_document</span></code> is a sub-class
of <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>, <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code> is not a polymorphic type; the
<codeclass="computeroutput"><spanclass="identifier">xml_node</span></code> is the handle to
document node; it can point to any node in the document, including document
itself. There is a common interface for nodes of all types; the actual node
type can be queried via <codeclass="computeroutput"><spanclass="identifier">xml_node</span><spanclass="special">::</span><spanclass="identifier">type</span><spanclass="special">()</span></code> method. Note that <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>
is only a handle to the actual node, not the node itself - you can have several
to the same underlying object. Destroying <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>
handle does not destroy the node and does not remove it from the tree. The
size of <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code> is equal
to that of a pointer, so it is nothing more than a lightweight wrapper around
pointer; you can safely pass or return <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>
objects by value without additional overhead.
</p>
<aname="node_null"></a><p>
There is a special value of <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>
type, known as null node or empty node (such nodes have type <codeclass="computeroutput"><spanclass="identifier">node_null</span></code>). It does not correspond to any
node in any document, and thus resembles null pointer. However, all operations
are defined on empty nodes; generally the operations don't do anything and
return empty nodes/attributes or empty strings as their result (see documentation
for specific functions for more detailed information). This is useful for
chaining calls; i.e. you can get the grandparent of a node like so: <codeclass="computeroutput"><spanclass="identifier">node</span><spanclass="special">.</span><spanclass="identifier">parent</span><spanclass="special">().</span><spanclass="identifier">parent</span><spanclass="special">()</span></code>; if a node is a null node or it does not
have a parent, the first <codeclass="computeroutput"><spanclass="identifier">parent</span><spanclass="special">()</span></code> call returns null node; the second <codeclass="computeroutput"><spanclass="identifier">parent</span><spanclass="special">()</span></code>
call then also returns null node, so you don't have to check for errors twice.
</p>
<aname="xml_attribute"></a><p>
<codeclass="computeroutput"><spanclass="identifier">xml_attribute</span></code> is the handle
to an XML attribute; it has the same semantics as <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>,
i.e. there can be several <codeclass="computeroutput"><spanclass="identifier">xml_attribute</span></code>
handles pointing to the same underlying object, there is a special null attribute
Both <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code> and <codeclass="computeroutput"><spanclass="identifier">xml_attribute</span></code> have the default constructor
<codeclass="computeroutput"><spanclass="identifier">xml_node</span></code> and <codeclass="computeroutput"><spanclass="identifier">xml_attribute</span></code> try to behave like pointers,
that is, they can be compared with other objects of the same type, making
it possible to use them as keys of associative containers. All handles to
the same underlying object are equal, and any two handles to different underlying
objects are not equal. Null handles only compare as equal to themselves.
The result of relational comparison can not be reliably determined from the
order of nodes in file or other ways. Do not use relational comparison operators
except for search optimization (i.e. associative container keys).
Additionally handles they can be implicitly cast to boolean-like objects,
so that you can test if the node/attribute is empty by just doing <codeclass="computeroutput"><spanclass="keyword">if</span><spanclass="special">(</span><spanclass="identifier">node</span><spanclass="special">)</span><spanclass="special">{</span><spanclass="special">...</span>
<spanclass="special">}</span></code> or <codeclass="computeroutput"><spanclass="keyword">if</span>
Alternatively you can check if a given <codeclass="computeroutput"><spanclass="identifier">xml_node</span></code>/<codeclass="computeroutput"><spanclass="identifier">xml_attribute</span></code> handle is null by calling
Nodes and attributes do not exist outside of document tree, so you can't
create them without adding them to some document. Once underlying node/attribute
objects are destroyed, the handles to those objects become invalid. While
this means that destruction of the entire tree invalidates all node/attribute
handles, it also means that destroying a subtree (by calling <codeclass="computeroutput"><spanclass="identifier">remove_child</span></code>) or removing an attribute
invalidates the corresponding handles. There is no way to check handle validity;
you have to ensure correctness through external mechanisms.
There are two choices of interface and internal representation when configuring
pugixml: you can either choose the UTF-8 (also called char) interface or
UTF-16/32 (also called wchar_t) one. The choice is controlled via <codeclass="computeroutput"><spanclass="identifier">PUGIXML_WCHAR_MODE</span></code> define; you can set
it via <codeclass="filename">pugiconfig.hpp</code> or via preprocessor options, as discussed in <aclass="xref"href="install.html#manual.install.building.config"title="Additional configuration options"> Additional configuration
options</a>.
If this define is set, the wchar_t interface is used; otherwise (by default)
the char interface is used. The exact wide character encoding is assumed
to be either UTF-16 or UTF-32 and is determined based on size of <codeclass="computeroutput"><spanclass="keyword">wchar_t</span></code> type.
There is a special type, <codeclass="computeroutput"><spanclass="identifier">pugi</span><spanclass="special">::</span><spanclass="identifier">char_t</span></code>,
that is defined as the character type and depends on the library configuration;
it will be also used in the documentation hereafter. There is also a type
<codeclass="computeroutput"><spanclass="identifier">pugi</span><spanclass="special">::</span><spanclass="identifier">string_t</span></code>, which is defined as the STL string
of the character type; it corresponds to <codeclass="computeroutput"><spanclass="identifier">std</span><spanclass="special">::</span><spanclass="identifier">string</span></code>
in char mode and to <codeclass="computeroutput"><spanclass="identifier">std</span><spanclass="special">::</span><spanclass="identifier">wstring</span></code> in wchar_t mode.
</p>
<p>
In addition to the interface, the internal implementation changes to store
XML data as <codeclass="computeroutput"><spanclass="identifier">pugi</span><spanclass="special">::</span><spanclass="identifier">char_t</span></code>; this means that these two modes
have different memory usage characteristics. The conversion to <codeclass="computeroutput"><spanclass="identifier">pugi</span><spanclass="special">::</span><spanclass="identifier">char_t</span></code> upon document loading and from
<codeclass="computeroutput"><spanclass="identifier">pugi</span><spanclass="special">::</span><spanclass="identifier">char_t</span></code> upon document saving happen automatically,
which also carries minor performance penalty. The general advice however
is to select the character mode based on usage scenario, i.e. if UTF-8 is
inconvenient to process and most of your XML data is localized, wchar_t mode
is probably a better choice.
</p>
<aname="as_utf8"></a><aname="as_wide"></a><p>
There are cases when you'll have to convert string data between UTF-8 and
wchar_t encodings; the following helper functions are provided for such purposes:
Both functions accept null-terminated string as an argument <codeclass="computeroutput"><spanclass="identifier">str</span></code>, and return the converted string.
it is safe to call free functions from multiple threads
</li>
<liclass="listitem">
it is safe to perform concurrent read-only accesses to the same tree
(all constant member functions do not modify the tree)
</li>
<liclass="listitem">
it is safe to perform concurrent read/write accesses, if there is only
one read or write access to the single tree at a time
</li>
</ul></div>
<p>
Concurrent modification and traversing of a single tree requires synchronization,
for example via reader-writer lock. Modification includes altering document
structure and altering individual node/attribute data, i.e. changing names/values.
</p>
<p>
The only exception is <codeclass="computeroutput"><spanclass="identifier">set_memory_management_functions</span></code>;
it modifies global variables and as such is not thread-safe. Its usage policy
has more restrictions, see <aclass="xref"href="dom.html#manual.dom.memory.custom"title="Custom memory allocation/deallocation functions"> Custom memory allocation/deallocation
or <codeclass="computeroutput"><spanclass="identifier">xml_node</span><spanclass="special">::</span><spanclass="identifier">find_node</span></code>) do not provide any exception
guarantees beyond the ones provided by callback.
</p>
<p>
XPath functions may throw <codeclass="computeroutput"><spanclass="identifier">xpath_exception</span></code>
on parsing error; also, XPath implementation uses STL, and thus may throw
i.e. <codeclass="computeroutput"><spanclass="identifier">std</span><spanclass="special">::</span><spanclass="identifier">bad_alloc</span></code> in low memory conditions. Still,
XPath functions provide strong exception guarantee.
Allocation function is called with the size (in bytes) as an argument and
should return a pointer to memory block with alignment that is suitable
for pointer storage and size that is greater or equal to the requested
one. If the allocation fails, the function has to return null pointer (throwing
an exception from allocation function results in undefined behavior). Deallocation
function is called with the pointer that was returned by the previous call
or with a null pointer; null pointer deallocation should be handled as
a no-op. If memory management functions are not thread-safe, library thread
safety is not guaranteed.
</p>
<p>
This is a simple example of custom memory management (<ahref="../samples/custom_memory_management.cpp"target="_top">samples/custom_memory_management.cpp</a>):
Constructing a document object using the default constructor does not result
in any allocations; document node is stored inside the <codeclass="computeroutput"><spanclass="identifier">xml_document</span></code>
object.
</p>
<p>
When the document is loaded from file/buffer, unless an inplace loading
function is used (see <aclass="xref"href="loading.html#manual.loading.memory"title="Loading document from memory"> Loading document from memory</a>), a complete copy of character
stream is made; all names/values of nodes and attributes are allocated
in this buffer. This buffer is allocated via a single large allocation
and is only freed when document memory is reclaimed (i.e. if the <codeclass="computeroutput"><spanclass="identifier">xml_document</span></code> object is destroyed or if
another document is loaded in the same object). Also when loading from
file or stream, an additional large allocation may be performed if encoding
conversion is required; a temporary buffer is allocated, and it is freed
before load function returns.
</p>
<p>
All additional memory, such as memory for document structure (node/attribute
objects) and memory for node/attribute names/values is allocated in pages
on the order of 32 kilobytes; actual objects are allocated inside the pages
using a memory management scheme optimized for fast allocation/deallocation
of many small objects. Because of the scheme specifics, the pages are only
destroyed if all objects inside them are destroyed; also, generally destroying
an object does not mean that subsequent object creation will reuse the
same memory. This means that it is possible to devise a usage scheme which
will lead to higher memory usage than expected; one example is adding a
lot of nodes, and them removing all even numbered ones; not a single page
is reclaimed in the process. However this is an example specifically crafted
to produce unsatisfying behavior; in all practical usage scenarios the
memory consumption is less than that of a general-purpose allocator because