docs: Remove old HTML documentation

This commit is contained in:
Arseny Kapoulkine 2015-03-21 21:04:28 -07:00
parent 1a450b302a
commit 2843f91d00
12 changed files with 0 additions and 9149 deletions

View file

@ -1,205 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>pugixml 1.6</title>
<link rel="stylesheet" href="pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="manual.html" title="pugixml 1.6">
<link rel="next" href="manual/install.html" title="Installation">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<b>Overview</b> |
<a href="manual/install.html">Installation</a> |
Document:
<a href="manual/dom.html">Object model</a> &middot; <a href="manual/loading.html">Loading</a> &middot; <a href="manual/access.html">Accessing</a> &middot; <a href="manual/modify.html">Modifying</a> &middot; <a href="manual/saving.html">Saving</a> |
<a href="manual/xpath.html">XPath</a> |
<a href="manual/apiref.html">API Reference</a> |
<a href="manual/toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav"><a accesskey="n" href="manual/install.html"><img src="images/next.png" alt="Next"></a></div></td>
</tr></table>
<hr>
<div class="book"><div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.overview"></a><a class="link" href="manual.html#manual.overview" title="Overview"> Overview</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="manual.html#manual.overview.introduction"> Introduction</a></span></dt>
<dt><span class="section"><a href="manual.html#manual.overview.feedback"> Feedback</a></span></dt>
<dt><span class="section"><a href="manual.html#manual.overview.thanks"> Acknowledgments</a></span></dt>
<dt><span class="section"><a href="manual.html#manual.overview.license"> License</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.overview.introduction"></a><a class="link" href="manual.html#manual.overview.introduction" title="Introduction"> Introduction</a>
</h3></div></div></div>
<p>
<a href="http://pugixml.org/" target="_top">pugixml</a> is a light-weight C++ XML
processing library. It consists of a DOM-like interface with rich traversal/modification
capabilities, an extremely fast XML parser which constructs the DOM tree
from an XML file/buffer, and an <a class="link" href="manual/xpath.html" title="XPath">XPath 1.0 implementation</a>
for complex data-driven tree queries. Full Unicode support is also available,
with <a class="link" href="manual/dom.html#manual.dom.unicode" title="Unicode interface">two Unicode interface variants</a>
and conversions between different Unicode encodings (which happen automatically
during parsing/saving). The library is <a class="link" href="manual/install.html#manual.install.portability" title="Portability">extremely
portable</a> and easy to integrate and use. pugixml is developed and maintained
since 2006 and has many users. All code is distributed under the <a class="link" href="manual.html#manual.overview.license" title="License">MIT
license</a>, making it completely free to use in both open-source and
proprietary applications.
</p>
<p>
pugixml enables very fast, convenient and memory-efficient XML document processing.
However, since pugixml has a DOM parser, it can't process XML documents that
do not fit in memory; also the parser is a non-validating one, so if you
need DTD or XML Schema validation, the library is not for you.
</p>
<p>
This is the complete manual for pugixml, which describes all features of
the library in detail. If you want to start writing code as quickly as possible,
you are advised to <a href="quickstart.html" target="_top">read the quick start guide
first</a>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
No documentation is perfect, neither is this one. If you encounter a description
that is unclear, please file an issue as described in <a class="xref" href="manual.html#manual.overview.feedback" title="Feedback"> Feedback</a>.
Also if you can spare the time for a full proof-reading, including spelling
and grammar, that would be great! Please <a class="link" href="manual.html#email">send me
an e-mail</a>; as a token of appreciation, your name will be included
into the <a class="link" href="manual.html#manual.overview.thanks" title="Acknowledgments">corresponding section</a>
of this documentation.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.overview.feedback"></a><a class="link" href="manual.html#manual.overview.feedback" title="Feedback"> Feedback</a>
</h3></div></div></div>
<p>
If you believe you've found a bug in pugixml (bugs include compilation problems
(errors/warnings), crashes, performance degradation and incorrect behavior),
please file an issue via <a href="https://github.com/zeux/pugixml/issues/new" target="_top">issue
submission form</a>. Be sure to include the relevant information so that
the bug can be reproduced: the version of pugixml, compiler version and target
architecture, the code that uses pugixml and exhibits the bug, etc.
</p>
<p>
Feature requests can be reported the same way as bugs, so if you're missing
some functionality in pugixml or if the API is rough in some places and you
can suggest an improvement, <a href="https://github.com/zeux/pugixml/issues/new" target="_top">file
an issue</a>. However please note that there are many factors when considering
API changes (compatibility with previous versions, API redundancy, etc.),
so generally features that can be implemented via a small function without
pugixml modification are not accepted. However, all rules have exceptions.
</p>
<p>
If you have a contribution to pugixml, such as build script for some build
system/IDE, or a well-designed set of helper functions, or a binding to some
language other than C++, please <a href="https://github.com/zeux/pugixml/issues/new" target="_top">file
an issue</a>. You can include the relevant patches as issue attachments.
Your contribution has to be distributed under the terms of a license that's
compatible with pugixml license; i.e. GPL/LGPL licensed code is not accepted.
</p>
<a name="email"></a><p>
If filing an issue is not possible due to privacy or other concerns, you
can contact pugixml author by e-mail directly: <a href="mailto:arseny.kapoulkine@gmail.com" target="_top">arseny.kapoulkine@gmail.com</a>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.overview.thanks"></a><a class="link" href="manual.html#manual.overview.thanks" title="Acknowledgments"> Acknowledgments</a>
</h3></div></div></div>
<p>
pugixml could not be developed without the help from many people; some of
them are listed in this section. If you've played a part in pugixml development
and you can not find yourself on this list, I'm truly sorry; please <a class="link" href="manual.html#email">send me an e-mail</a> so I can fix this.
</p>
<p>
Thanks to <span class="bold"><strong>Kristen Wegner</strong></span> for pugxml parser,
which was used as a basis for pugixml.
</p>
<p>
Thanks to <span class="bold"><strong>Neville Franks</strong></span> for contributions
to pugxml parser.
</p>
<p>
Thanks to <span class="bold"><strong>Artyom Palvelev</strong></span> for suggesting
a lazy gap contraction approach.
</p>
<p>
Thanks to <span class="bold"><strong>Vyacheslav Egorov</strong></span> for documentation
proofreading.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.overview.license"></a><a class="link" href="manual.html#manual.overview.license" title="License"> License</a>
</h3></div></div></div>
<p>
The pugixml library is distributed under the MIT license:
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
Copyright (c) 2006-2014 Arseny Kapoulkine
</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
</p>
</blockquote></div>
<p>
This means that you can freely use pugixml in your applications, both open-source
and proprietary. If you use pugixml in a product, it is sufficient to add
an acknowledgment like this to the product distribution:
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
This software is based on pugixml library (http://pugixml.org).<br>
pugixml
is Copyright (C) 2006-2014 Arseny Kapoulkine.
</p></blockquote></div>
</div>
</div></div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: March 20, 2015 at 07:16:25 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<b>Overview</b> |
<a href="manual/install.html">Installation</a> |
Document:
<a href="manual/dom.html">Object model</a> &middot; <a href="manual/loading.html">Loading</a> &middot; <a href="manual/access.html">Accessing</a> &middot; <a href="manual/modify.html">Modifying</a> &middot; <a href="manual/saving.html">Saving</a> |
<a href="manual/xpath.html">XPath</a> |
<a href="manual/apiref.html">API Reference</a> |
<a href="manual/toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav"><a accesskey="n" href="manual/install.html"><img src="images/next.png" alt="Next"></a></div></td>
</tr></table>
</body>
</html>

View file

@ -1,900 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Accessing document data</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="loading.html" title="Loading document">
<link rel="next" href="modify.html" title="Modifying document data">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <b>Accessing</b> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="loading.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="modify.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.access"></a><a class="link" href="access.html" title="Accessing document data"> Accessing document data</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="access.html#manual.access.basic"> Basic traversal functions</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.nodedata"> Getting node data</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.attrdata"> Getting attribute data</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.contents"> Contents-based traversal functions</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.rangefor"> Range-based for-loop support</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.iterators"> Traversing node/attribute lists
via iterators</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.walker"> Recursive traversal with xml_tree_walker</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.predicate"> Searching for nodes/attributes
with predicates</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.text"> Working with text contents</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.misc"> Miscellaneous functions</a></span></dt>
</dl></div>
<p>
pugixml features an extensive interface for getting various types of data from
the document and for traversing the document. This section provides documentation
for all such functions that do not modify the tree except for XPath-related
functions; see <a class="xref" href="xpath.html" title="XPath"> XPath</a> for XPath reference. As discussed in <a class="xref" href="dom.html#manual.dom.cpp" title="C++ interface"> C++ interface</a>,
there are two types of handles to tree data - <a class="link" href="dom.html#xml_node">xml_node</a>
and <a class="link" href="dom.html#xml_attribute">xml_attribute</a>. The handles have special
null (empty) values which propagate through various functions and thus are
useful for writing more concise code; see <a class="link" href="dom.html#node_null">this description</a>
for details. The documentation in this section will explicitly state the results
of all function in case of null inputs.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.basic"></a><a class="link" href="access.html#manual.access.basic" title="Basic traversal functions"> Basic traversal functions</a>
</h3></div></div></div>
<a name="xml_node::parent"></a><a name="xml_node::first_child"></a><a name="xml_node::last_child"></a><a name="xml_node::next_sibling"></a><a name="xml_node::previous_sibling"></a><a name="xml_node::first_attribute"></a><a name="xml_node::last_attribute"></a><a name="xml_attribute::next_attribute"></a><a name="xml_attribute::previous_attribute"></a><p>
The internal representation of the document is a tree, where each node has
a list of child nodes (the order of children corresponds to their order in
the XML representation), and additionally element nodes have a list of attributes,
which is also ordered. Several functions are provided in order to let you
get from one node in the tree to the other. These functions roughly correspond
to the internal representation, and thus are usually building blocks for
other methods of traversing (i.e. XPath traversals are based on these functions).
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">parent</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">first_child</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">last_child</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">next_sibling</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">previous_sibling</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">first_attribute</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">last_attribute</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">next_attribute</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">previous_attribute</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">parent</span></code> function returns the
node's parent; all non-null nodes except the document have non-null parent.
<code class="computeroutput"><span class="identifier">first_child</span></code> and <code class="computeroutput"><span class="identifier">last_child</span></code> return the first and last child
of the node, respectively; note that only document nodes and element nodes
can have non-empty child node list. If node has no children, both functions
return null nodes. <code class="computeroutput"><span class="identifier">next_sibling</span></code>
and <code class="computeroutput"><span class="identifier">previous_sibling</span></code> return
the node that's immediately to the right/left of this node in the children
list, respectively - for example, in <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">a</span><span class="special">/&gt;&lt;</span><span class="identifier">b</span><span class="special">/&gt;&lt;</span><span class="identifier">c</span><span class="special">/&gt;</span></code>,
calling <code class="computeroutput"><span class="identifier">next_sibling</span></code> for
a handle that points to <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">b</span><span class="special">/&gt;</span></code>
results in a handle pointing to <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">c</span><span class="special">/&gt;</span></code>,
and calling <code class="computeroutput"><span class="identifier">previous_sibling</span></code>
results in handle pointing to <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">a</span><span class="special">/&gt;</span></code>.
If node does not have next/previous sibling (this happens if it is the last/first
node in the list, respectively), the functions return null nodes. <code class="computeroutput"><span class="identifier">first_attribute</span></code>, <code class="computeroutput"><span class="identifier">last_attribute</span></code>,
<code class="computeroutput"><span class="identifier">next_attribute</span></code> and <code class="computeroutput"><span class="identifier">previous_attribute</span></code> functions behave similarly
to the corresponding child node functions and allow to iterate through attribute
list in the same way.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Because of memory consumption reasons, attributes do not have a link to
their parent nodes. Thus there is no <code class="computeroutput"><span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">parent</span><span class="special">()</span></code> function.
</p></td></tr>
</table></div>
<p>
Calling any of the functions above on the null handle results in a null handle
- i.e. <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">().</span><span class="identifier">next_sibling</span><span class="special">()</span></code>
returns the second child of <code class="computeroutput"><span class="identifier">node</span></code>,
and null handle if <code class="computeroutput"><span class="identifier">node</span></code> is
null, has no children at all or if it has only one child node.
</p>
<p>
With these functions, you can iterate through all child nodes and display
all attributes like this (<a href="../samples/traverse_base.cpp" target="_top">samples/traverse_base.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">();</span> <span class="identifier">tool</span><span class="special">;</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool:"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute</span> <span class="identifier">attr</span> <span class="special">=</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">first_attribute</span><span class="special">();</span> <span class="identifier">attr</span><span class="special">;</span> <span class="identifier">attr</span> <span class="special">=</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">next_attribute</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"="</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.nodedata"></a><a class="link" href="access.html#manual.access.nodedata" title="Getting node data"> Getting node data</a>
</h3></div></div></div>
<a name="xml_node::name"></a><a name="xml_node::value"></a><p>
Apart from structural information (parent, child nodes, attributes), nodes
can have name and value, both of which are strings. Depending on node type,
name or value may be absent. <a class="link" href="dom.html#node_document">node_document</a>
nodes do not have a name or value, <a class="link" href="dom.html#node_element">node_element</a>
and <a class="link" href="dom.html#node_declaration">node_declaration</a> nodes always
have a name but never have a value, <a class="link" href="dom.html#node_pcdata">node_pcdata</a>,
<a class="link" href="dom.html#node_cdata">node_cdata</a>, <a class="link" href="dom.html#node_comment">node_comment</a>
and <a class="link" href="dom.html#node_doctype">node_doctype</a> nodes never have a name
but always have a value (it may be empty though), <a class="link" href="dom.html#node_pi">node_pi</a>
nodes always have a name and a value (again, value may be empty). In order
to get node's name or value, you can use the following functions:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
In case node does not have a name or value or if the node handle is null,
both functions return empty strings - they never return null pointers.
</p>
<a name="xml_node::child_value"></a><p>
It is common to store data as text contents of some node - i.e. <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;&lt;</span><span class="identifier">description</span><span class="special">&gt;</span><span class="identifier">This</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">node</span><span class="special">&lt;/</span><span class="identifier">description</span><span class="special">&gt;&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span></code>.
In this case, <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">description</span><span class="special">&gt;</span></code> node does not have a value, but instead
has a child of type <a class="link" href="dom.html#node_pcdata">node_pcdata</a> with value
<code class="computeroutput"><span class="string">"This is a node"</span></code>. pugixml
provides several helper functions to parse such data:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">child_value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">child_value</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_text</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">text</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">child_value</span><span class="special">()</span></code>
returns the value of the first child with type <a class="link" href="dom.html#node_pcdata">node_pcdata</a>
or <a class="link" href="dom.html#node_cdata">node_cdata</a>; <code class="computeroutput"><span class="identifier">child_value</span><span class="special">(</span><span class="identifier">name</span><span class="special">)</span></code>
is a simple wrapper for <code class="computeroutput"><span class="identifier">child</span><span class="special">(</span><span class="identifier">name</span><span class="special">).</span><span class="identifier">child_value</span><span class="special">()</span></code>.
For the above example, calling <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">child_value</span><span class="special">(</span><span class="string">"description"</span><span class="special">)</span></code> and <code class="computeroutput"><span class="identifier">description</span><span class="special">.</span><span class="identifier">child_value</span><span class="special">()</span></code> will both produce string <code class="computeroutput"><span class="string">"This is a node"</span></code>. If there is no
child with relevant type, or if the handle is null, <code class="computeroutput"><span class="identifier">child_value</span></code>
functions return empty string.
</p>
<p>
<code class="computeroutput"><span class="identifier">text</span><span class="special">()</span></code>
returns a special object that can be used for working with PCDATA contents
in more complex cases than just retrieving the value; it is described in
<a class="xref" href="access.html#manual.access.text" title="Working with text contents"> Working with text contents</a> sections.
</p>
<p>
There is an example of using some of these functions <a class="link" href="access.html#code_traverse_base_data">at
the end of the next section</a>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.attrdata"></a><a class="link" href="access.html#manual.access.attrdata" title="Getting attribute data"> Getting attribute data</a>
</h3></div></div></div>
<a name="xml_attribute::name"></a><a name="xml_attribute::value"></a><p>
All attributes have name and value, both of which are strings (value may
be empty). There are two corresponding accessors, like for <code class="computeroutput"><span class="identifier">xml_node</span></code>:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
In case the attribute handle is null, both functions return empty strings
- they never return null pointers.
</p>
<a name="xml_attribute::as_string"></a><p>
If you need a non-empty string if the attribute handle is null (for example,
you need to get the option value from XML attribute, but if it is not specified,
you need it to default to <code class="computeroutput"><span class="string">"sorted"</span></code>
instead of <code class="computeroutput"><span class="string">""</span></code>), you
can use <code class="computeroutput"><span class="identifier">as_string</span></code> accessor:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">as_string</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">def</span> <span class="special">=</span> <span class="string">""</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
It returns <code class="computeroutput"><span class="identifier">def</span></code> argument if
the attribute handle is null. If you do not specify the argument, the function
is equivalent to <code class="computeroutput"><span class="identifier">value</span><span class="special">()</span></code>.
</p>
<a name="xml_attribute::as_int"></a><a name="xml_attribute::as_uint"></a><a name="xml_attribute::as_double"></a><a name="xml_attribute::as_float"></a><a name="xml_attribute::as_bool"></a><a name="xml_attribute::as_llong"></a><a name="xml_attribute::as_ullong"></a><p>
In many cases attribute values have types that are not strings - i.e. an
attribute may always contain values that should be treated as integers, despite
the fact that they are represented as strings in XML. pugixml provides several
accessors that convert attribute value to some other type:
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">as_int</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">as_uint</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">as_double</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">float</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">as_float</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">as_bool</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">def</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">as_llong</span><span class="special">(</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">as_ullong</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">as_int</span></code>, <code class="computeroutput"><span class="identifier">as_uint</span></code>,
<code class="computeroutput"><span class="identifier">as_llong</span></code>, <code class="computeroutput"><span class="identifier">as_ullong</span></code>,
<code class="computeroutput"><span class="identifier">as_double</span></code> and <code class="computeroutput"><span class="identifier">as_float</span></code> convert attribute values to numbers.
If attribute handle is null or attribute value is empty, <code class="computeroutput"><span class="identifier">def</span></code>
argument is returned (which is 0 by default). Otherwise, all leading whitespace
characters are truncated, and the remaining string is parsed as an integer
number in either decimal or hexadecimal form (applicable to <code class="computeroutput"><span class="identifier">as_int</span></code>, <code class="computeroutput"><span class="identifier">as_uint</span></code>,
<code class="computeroutput"><span class="identifier">as_llong</span></code> and <code class="computeroutput"><span class="identifier">as_ullong</span></code>; hexadecimal format is used if
the number has <code class="computeroutput"><span class="number">0</span><span class="identifier">x</span></code>
or <code class="computeroutput"><span class="number">0</span><span class="identifier">X</span></code>
prefix) or as a floating point number in either decimal or scientific form
(<code class="computeroutput"><span class="identifier">as_double</span></code> or <code class="computeroutput"><span class="identifier">as_float</span></code>). Any extra characters are silently
discarded, i.e. <code class="computeroutput"><span class="identifier">as_int</span></code> will
return <code class="computeroutput"><span class="number">1</span></code> for string <code class="computeroutput"><span class="string">"1abc"</span></code>.
</p>
<p>
In case the input string contains a number that is out of the target numeric
range, the result is undefined.
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
Number conversion functions depend on current C locale as set with <code class="computeroutput"><span class="identifier">setlocale</span></code>, so may return unexpected results
if the locale is different from <code class="computeroutput"><span class="string">"C"</span></code>.
</p></td></tr>
</table></div>
<p>
<code class="computeroutput"><span class="identifier">as_bool</span></code> converts attribute
value to boolean as follows: if attribute handle is null, <code class="computeroutput"><span class="identifier">def</span></code>
argument is returned (which is <code class="computeroutput"><span class="keyword">false</span></code>
by default). If attribute value is empty, <code class="computeroutput"><span class="keyword">false</span></code>
is returned. Otherwise, <code class="computeroutput"><span class="keyword">true</span></code>
is returned if the first character is one of <code class="computeroutput"><span class="char">'1'</span><span class="special">,</span> <span class="char">'t'</span><span class="special">,</span>
<span class="char">'T'</span><span class="special">,</span> <span class="char">'y'</span><span class="special">,</span> <span class="char">'Y'</span></code>.
This means that strings like <code class="computeroutput"><span class="string">"true"</span></code>
and <code class="computeroutput"><span class="string">"yes"</span></code> are recognized
as <code class="computeroutput"><span class="keyword">true</span></code>, while strings like
<code class="computeroutput"><span class="string">"false"</span></code> and <code class="computeroutput"><span class="string">"no"</span></code> are recognized as <code class="computeroutput"><span class="keyword">false</span></code>. For more complex matching you'll have
to write your own function.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><span class="identifier">as_llong</span></code> and <code class="computeroutput"><span class="identifier">as_ullong</span></code> are only available if your
platform has reliable support for the <code class="computeroutput"><span class="keyword">long</span>
<span class="keyword">long</span></code> type, including string conversions.
</p></td></tr>
</table></div>
<a name="code_traverse_base_data"></a><p>
This is an example of using these functions, along with node data retrieval
ones (<a href="../samples/traverse_base.cpp" target="_top">samples/traverse_base.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">);</span> <span class="identifier">tool</span><span class="special">;</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">))</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">": AllowRemote "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"AllowRemote"</span><span class="special">).</span><span class="identifier">as_bool</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", Timeout "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Timeout"</span><span class="special">).</span><span class="identifier">as_int</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", Description '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">child_value</span><span class="special">(</span><span class="string">"Description"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"'\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.contents"></a><a class="link" href="access.html#manual.access.contents" title="Contents-based traversal functions"> Contents-based traversal functions</a>
</h3></div></div></div>
<a name="xml_node::child"></a><a name="xml_node::attribute"></a><a name="xml_node::next_sibling_name"></a><a name="xml_node::previous_sibling_name"></a><p>
Since a lot of document traversal consists of finding the node/attribute
with the correct name, there are special functions for that purpose:
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">child</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">attribute</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">next_sibling</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">previous_sibling</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">child</span></code> and <code class="computeroutput"><span class="identifier">attribute</span></code>
return the first child/attribute with the specified name; <code class="computeroutput"><span class="identifier">next_sibling</span></code>
and <code class="computeroutput"><span class="identifier">previous_sibling</span></code> return
the first sibling in the corresponding direction with the specified name.
All string comparisons are case-sensitive. In case the node handle is null
or there is no node/attribute with the specified name, null handle is returned.
</p>
<p>
<code class="computeroutput"><span class="identifier">child</span></code> and <code class="computeroutput"><span class="identifier">next_sibling</span></code>
functions can be used together to loop through all child nodes with the desired
name like this:
</p>
<pre class="programlisting"><span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">);</span> <span class="identifier">tool</span><span class="special">;</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">))</span>
</pre>
<a name="xml_node::find_child_by_attribute"></a><p>
Occasionally the needed node is specified not by the unique name but instead
by the value of some attribute; for example, it is common to have node collections
with each node having a unique id: <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">group</span><span class="special">&gt;&lt;</span><span class="identifier">item</span> <span class="identifier">id</span><span class="special">=</span><span class="string">"1"</span><span class="special">/&gt;</span> <span class="special">&lt;</span><span class="identifier">item</span> <span class="identifier">id</span><span class="special">=</span><span class="string">"2"</span><span class="special">/&gt;&lt;/</span><span class="identifier">group</span><span class="special">&gt;</span></code>. There are two functions for finding
child nodes based on the attribute values:
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">find_child_by_attribute</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">attr_name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">attr_value</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">find_child_by_attribute</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">attr_name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">attr_value</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
The three-argument function returns the first child node with the specified
name which has an attribute with the specified name/value; the two-argument
function skips the name test for the node, which can be useful for searching
in heterogeneous collections. If the node handle is null or if no node is
found, null handle is returned. All string comparisons are case-sensitive.
</p>
<p>
In all of the above functions, all arguments have to be valid strings; passing
null pointers results in undefined behavior.
</p>
<p>
This is an example of using these functions (<a href="../samples/traverse_base.cpp" target="_top">samples/traverse_base.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool for *.dae generation: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">find_child_by_attribute</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">,</span> <span class="string">"OutputFileMasks"</span><span class="special">,</span> <span class="string">"*.dae"</span><span class="special">).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">);</span> <span class="identifier">tool</span><span class="special">;</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">))</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.rangefor"></a><a class="link" href="access.html#manual.access.rangefor" title="Range-based for-loop support"> Range-based for-loop support</a>
</h3></div></div></div>
<a name="xml_node::children"></a><a name="xml_node::attributes"></a><p>
If your C++ compiler supports range-based for-loop (this is a C++11 feature,
at the time of writing it's supported by Microsoft Visual Studio 11 Beta,
GCC 4.6 and Clang 3.0), you can use it to enumerate nodes/attributes. Additional
helpers are provided to support this; note that they are also compatible
with <a href="http://www.boost.org/libs/foreach/" target="_top">Boost Foreach</a>,
and possibly other pre-C++11 foreach facilities.
</p>
<pre class="programlisting"><span class="emphasis"><em>implementation-defined type</em></span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">children</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="emphasis"><em>implementation-defined type</em></span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">children</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="emphasis"><em>implementation-defined type</em></span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">attributes</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">children</span></code> function allows
you to enumerate all child nodes; <code class="computeroutput"><span class="identifier">children</span></code>
function with <code class="computeroutput"><span class="identifier">name</span></code> argument
allows you to enumerate all child nodes with a specific name; <code class="computeroutput"><span class="identifier">attributes</span></code> function allows you to enumerate
all attributes of the node. Note that you can also use node object itself
in a range-based for construct, which is equivalent to using <code class="computeroutput"><span class="identifier">children</span><span class="special">()</span></code>.
</p>
<p>
This is an example of using these functions (<a href="../samples/traverse_rangefor.cpp" target="_top">samples/traverse_rangefor.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span><span class="special">:</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">children</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">))</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool:"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute</span> <span class="identifier">attr</span><span class="special">:</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attributes</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"="</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">child</span><span class="special">:</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">children</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", child "</span> <span class="special">&lt;&lt;</span> <span class="identifier">child</span><span class="special">.</span><span class="identifier">name</span><span class="special">();</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.iterators"></a><a class="link" href="access.html#manual.access.iterators" title="Traversing node/attribute lists via iterators"> Traversing node/attribute lists
via iterators</a>
</h3></div></div></div>
<a name="xml_node_iterator"></a><a name="xml_attribute_iterator"></a><a name="xml_node::begin"></a><a name="xml_node::end"></a><a name="xml_node::attributes_begin"></a><a name="xml_node::attributes_end"></a><p>
Child node lists and attribute lists are simply double-linked lists; while
you can use <code class="computeroutput"><span class="identifier">previous_sibling</span></code>/<code class="computeroutput"><span class="identifier">next_sibling</span></code> and other such functions for
iteration, pugixml additionally provides node and attribute iterators, so
that you can treat nodes as containers of other nodes or attributes:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">xml_node_iterator</span><span class="special">;</span>
<span class="keyword">class</span> <span class="identifier">xml_attribute_iterator</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">xml_node_iterator</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">iterator</span><span class="special">;</span>
<span class="identifier">iterator</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">iterator</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">xml_attribute_iterator</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">attribute_iterator</span><span class="special">;</span>
<span class="identifier">attribute_iterator</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">attributes_begin</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">attribute_iterator</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">attributes_end</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">begin</span></code> and <code class="computeroutput"><span class="identifier">attributes_begin</span></code>
return iterators that point to the first node/attribute, respectively; <code class="computeroutput"><span class="identifier">end</span></code> and <code class="computeroutput"><span class="identifier">attributes_end</span></code>
return past-the-end iterator for node/attribute list, respectively - this
iterator can't be dereferenced, but decrementing it results in an iterator
pointing to the last element in the list (except for empty lists, where decrementing
past-the-end iterator results in undefined behavior). Past-the-end iterator
is commonly used as a termination value for iteration loops (see sample below).
If you want to get an iterator that points to an existing handle, you can
construct the iterator with the handle as a single constructor argument,
like so: <code class="computeroutput"><span class="identifier">xml_node_iterator</span><span class="special">(</span><span class="identifier">node</span><span class="special">)</span></code>.
For <code class="computeroutput"><span class="identifier">xml_attribute_iterator</span></code>,
you'll have to provide both an attribute and its parent node.
</p>
<p>
<code class="computeroutput"><span class="identifier">begin</span></code> and <code class="computeroutput"><span class="identifier">end</span></code>
return equal iterators if called on null node; such iterators can't be dereferenced.
<code class="computeroutput"><span class="identifier">attributes_begin</span></code> and <code class="computeroutput"><span class="identifier">attributes_end</span></code> behave the same way. For
correct iterator usage this means that child node/attribute collections of
null nodes appear to be empty.
</p>
<p>
Both types of iterators have bidirectional iterator semantics (i.e. they
can be incremented and decremented, but efficient random access is not supported)
and support all usual iterator operations - comparison, dereference, etc.
The iterators are invalidated if the node/attribute objects they're pointing
to are removed from the tree; adding nodes/attributes does not invalidate
any iterators.
</p>
<p>
Here is an example of using iterators for document traversal (<a href="../samples/traverse_iter.cpp" target="_top">samples/traverse_iter.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span> <span class="special">++</span><span class="identifier">it</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool:"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute_iterator</span> <span class="identifier">ait</span> <span class="special">=</span> <span class="identifier">it</span><span class="special">-&gt;</span><span class="identifier">attributes_begin</span><span class="special">();</span> <span class="identifier">ait</span> <span class="special">!=</span> <span class="identifier">it</span><span class="special">-&gt;</span><span class="identifier">attributes_end</span><span class="special">();</span> <span class="special">++</span><span class="identifier">ait</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span> <span class="special">&lt;&lt;</span> <span class="identifier">ait</span><span class="special">-&gt;</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"="</span> <span class="special">&lt;&lt;</span> <span class="identifier">ait</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
Node and attribute iterators are somewhere in the middle between const
and non-const iterators. While dereference operation yields a non-constant
reference to the object, so that you can use it for tree modification operations,
modifying this reference by assignment - i.e. passing iterators to a function
like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sort</span></code> - will not give expected results,
as assignment modifies local handle that's stored in the iterator.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.walker"></a><a class="link" href="access.html#manual.access.walker" title="Recursive traversal with xml_tree_walker"> Recursive traversal with xml_tree_walker</a>
</h3></div></div></div>
<a name="xml_tree_walker"></a><p>
The methods described above allow traversal of immediate children of some
node; if you want to do a deep tree traversal, you'll have to do it via a
recursive function or some equivalent method. However, pugixml provides a
helper for depth-first traversal of a subtree. In order to use it, you have
to implement <code class="computeroutput"><span class="identifier">xml_tree_walker</span></code>
interface and to call <code class="computeroutput"><span class="identifier">traverse</span></code>
function:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">xml_tree_walker</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">virtual</span> <span class="keyword">bool</span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
<span class="keyword">virtual</span> <span class="keyword">bool</span> <span class="identifier">for_each</span><span class="special">(</span><span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="keyword">virtual</span> <span class="keyword">bool</span> <span class="identifier">end</span><span class="special">(</span><span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
<span class="keyword">int</span> <span class="identifier">depth</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">traverse</span><span class="special">(</span><span class="identifier">xml_tree_walker</span><span class="special">&amp;</span> <span class="identifier">walker</span><span class="special">);</span>
</pre>
<a name="xml_tree_walker::begin"></a><a name="xml_tree_walker::for_each"></a><a name="xml_tree_walker::end"></a><a name="xml_node::traverse"></a><p>
The traversal is launched by calling <code class="computeroutput"><span class="identifier">traverse</span></code>
function on traversal root and proceeds as follows:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
First, <code class="computeroutput"><span class="identifier">begin</span></code> function
is called with traversal root as its argument.
</li>
<li class="listitem">
Then, <code class="computeroutput"><span class="identifier">for_each</span></code> function
is called for all nodes in the traversal subtree in depth first order,
excluding the traversal root. Node is passed as an argument.
</li>
<li class="listitem">
Finally, <code class="computeroutput"><span class="identifier">end</span></code> function
is called with traversal root as its argument.
</li>
</ul></div>
<p>
If <code class="computeroutput"><span class="identifier">begin</span></code>, <code class="computeroutput"><span class="identifier">end</span></code>
or any of the <code class="computeroutput"><span class="identifier">for_each</span></code> calls
return <code class="computeroutput"><span class="keyword">false</span></code>, the traversal
is terminated and <code class="computeroutput"><span class="keyword">false</span></code> is returned
as the traversal result; otherwise, the traversal results in <code class="computeroutput"><span class="keyword">true</span></code>. Note that you don't have to override
<code class="computeroutput"><span class="identifier">begin</span></code> or <code class="computeroutput"><span class="identifier">end</span></code>
functions; their default implementations return <code class="computeroutput"><span class="keyword">true</span></code>.
</p>
<a name="xml_tree_walker::depth"></a><p>
You can get the node's depth relative to the traversal root at any point
by calling <code class="computeroutput"><span class="identifier">depth</span></code> function.
It returns <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code>
if called from <code class="computeroutput"><span class="identifier">begin</span></code>/<code class="computeroutput"><span class="identifier">end</span></code>, and returns 0-based depth if called
from <code class="computeroutput"><span class="identifier">for_each</span></code> - depth is
0 for all children of the traversal root, 1 for all grandchildren and so
on.
</p>
<p>
This is an example of traversing tree hierarchy with xml_tree_walker (<a href="../samples/traverse_walker.cpp" target="_top">samples/traverse_walker.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">simple_walker</span><span class="special">:</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_tree_walker</span>
<span class="special">{</span>
<span class="keyword">virtual</span> <span class="keyword">bool</span> <span class="identifier">for_each</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="identifier">depth</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span><span class="special">;</span> <span class="comment">// indentation
</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">node_types</span><span class="special">[</span><span class="identifier">node</span><span class="special">.</span><span class="identifier">type</span><span class="special">()]</span> <span class="special">&lt;&lt;</span> <span class="string">": name='"</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"', value='"</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"'\n"</span><span class="special">;</span>
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span> <span class="comment">// continue traversal
</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">simple_walker</span> <span class="identifier">walker</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">traverse</span><span class="special">(</span><span class="identifier">walker</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.predicate"></a><a class="link" href="access.html#manual.access.predicate" title="Searching for nodes/attributes with predicates"> Searching for nodes/attributes
with predicates</a>
</h3></div></div></div>
<a name="xml_node::find_attribute"></a><a name="xml_node::find_child"></a><a name="xml_node::find_node"></a><p>
While there are existing functions for getting a node/attribute with known
contents, they are often not sufficient for simple queries. As an alternative
for manual iteration through nodes/attributes until the needed one is found,
you can make a predicate and call one of <code class="computeroutput"><span class="identifier">find_</span></code>
functions:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Predicate</span><span class="special">&gt;</span> <span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">find_attribute</span><span class="special">(</span><span class="identifier">Predicate</span> <span class="identifier">pred</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Predicate</span><span class="special">&gt;</span> <span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">find_child</span><span class="special">(</span><span class="identifier">Predicate</span> <span class="identifier">pred</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Predicate</span><span class="special">&gt;</span> <span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">find_node</span><span class="special">(</span><span class="identifier">Predicate</span> <span class="identifier">pred</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
The predicate should be either a plain function or a function object which
accepts one argument of type <code class="computeroutput"><span class="identifier">xml_attribute</span></code>
(for <code class="computeroutput"><span class="identifier">find_attribute</span></code>) or
<code class="computeroutput"><span class="identifier">xml_node</span></code> (for <code class="computeroutput"><span class="identifier">find_child</span></code> and <code class="computeroutput"><span class="identifier">find_node</span></code>),
and returns <code class="computeroutput"><span class="keyword">bool</span></code>. The predicate
is never called with null handle as an argument.
</p>
<p>
<code class="computeroutput"><span class="identifier">find_attribute</span></code> function iterates
through all attributes of the specified node, and returns the first attribute
for which the predicate returned <code class="computeroutput"><span class="keyword">true</span></code>.
If the predicate returned <code class="computeroutput"><span class="keyword">false</span></code>
for all attributes or if there were no attributes (including the case where
the node is null), null attribute is returned.
</p>
<p>
<code class="computeroutput"><span class="identifier">find_child</span></code> function iterates
through all child nodes of the specified node, and returns the first node
for which the predicate returned <code class="computeroutput"><span class="keyword">true</span></code>.
If the predicate returned <code class="computeroutput"><span class="keyword">false</span></code>
for all nodes or if there were no child nodes (including the case where the
node is null), null node is returned.
</p>
<p>
<code class="computeroutput"><span class="identifier">find_node</span></code> function performs
a depth-first traversal through the subtree of the specified node (excluding
the node itself), and returns the first node for which the predicate returned
<code class="computeroutput"><span class="keyword">true</span></code>. If the predicate returned
<code class="computeroutput"><span class="keyword">false</span></code> for all nodes or if subtree
was empty, null node is returned.
</p>
<p>
This is an example of using predicate-based functions (<a href="../samples/traverse_predicate.cpp" target="_top">samples/traverse_predicate.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">small_timeout</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Timeout"</span><span class="special">).</span><span class="identifier">as_int</span><span class="special">()</span> <span class="special">&lt;</span> <span class="number">20</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">struct</span> <span class="identifier">allow_remote_predicate</span>
<span class="special">{</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute</span> <span class="identifier">attr</span><span class="special">)</span> <span class="keyword">const</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">strcmp</span><span class="special">(</span><span class="identifier">attr</span><span class="special">.</span><span class="identifier">name</span><span class="special">(),</span> <span class="string">"AllowRemote"</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span><span class="special">)</span> <span class="keyword">const</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"AllowRemote"</span><span class="special">).</span><span class="identifier">as_bool</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Find child via predicate (looks for direct children only)
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">find_child</span><span class="special">(</span><span class="identifier">allow_remote_predicate</span><span class="special">()).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// Find node via predicate (looks for all descendants in depth-first order)
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">find_node</span><span class="special">(</span><span class="identifier">allow_remote_predicate</span><span class="special">()).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// Find attribute via predicate
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">last_child</span><span class="special">().</span><span class="identifier">find_attribute</span><span class="special">(</span><span class="identifier">allow_remote_predicate</span><span class="special">()).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// We can use simple functions instead of function objects
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">find_child</span><span class="special">(</span><span class="identifier">small_timeout</span><span class="special">).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.text"></a><a class="link" href="access.html#manual.access.text" title="Working with text contents"> Working with text contents</a>
</h3></div></div></div>
<a name="xml_text"></a><p>
It is common to store data as text contents of some node - i.e. <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;&lt;</span><span class="identifier">description</span><span class="special">&gt;</span><span class="identifier">This</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">node</span><span class="special">&lt;/</span><span class="identifier">description</span><span class="special">&gt;&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span></code>.
In this case, <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">description</span><span class="special">&gt;</span></code> node does not have a value, but instead
has a child of type <a class="link" href="dom.html#node_pcdata">node_pcdata</a> with value
<code class="computeroutput"><span class="string">"This is a node"</span></code>. pugixml
provides a special class, <code class="computeroutput"><span class="identifier">xml_text</span></code>,
to work with such data. Working with text objects to modify data is described
in <a class="link" href="modify.html#manual.modify.text" title="Working with text contents">the documentation for modifying document
data</a>; this section describes the access interface of <code class="computeroutput"><span class="identifier">xml_text</span></code>.
</p>
<a name="xml_node::text"></a><p>
You can get the text object from a node by using <code class="computeroutput"><span class="identifier">text</span><span class="special">()</span></code> method:
</p>
<pre class="programlisting"><span class="identifier">xml_text</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">text</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
If the node has a type <code class="computeroutput"><span class="identifier">node_pcdata</span></code>
or <code class="computeroutput"><span class="identifier">node_cdata</span></code>, then the node
itself is used to return data; otherwise, a first child node of type <code class="computeroutput"><span class="identifier">node_pcdata</span></code> or <code class="computeroutput"><span class="identifier">node_cdata</span></code>
is used.
</p>
<a name="xml_text::empty"></a><a name="xml_text::unspecified_bool_type"></a><p>
You can check if the text object is bound to a valid PCDATA/CDATA node by
using it as a boolean value, i.e. <code class="computeroutput"><span class="keyword">if</span>
<span class="special">(</span><span class="identifier">text</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span>
<span class="special">}</span></code> or <code class="computeroutput"><span class="keyword">if</span>
<span class="special">(!</span><span class="identifier">text</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span>
<span class="special">}</span></code>. Alternatively you can check it
by using the <code class="computeroutput"><span class="identifier">empty</span><span class="special">()</span></code>
method:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">empty</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<a name="xml_text::get"></a><p>
Given a text object, you can get the contents (i.e. the value of PCDATA/CDATA
node) by using the following function:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
In case text object is empty, the function returns an empty string - it never
returns a null pointer.
</p>
<a name="xml_text::as_string"></a><a name="xml_text::as_int"></a><a name="xml_text::as_uint"></a><a name="xml_text::as_double"></a><a name="xml_text::as_float"></a><a name="xml_text::as_bool"></a><a name="xml_text::as_llong"></a><a name="xml_text::as_ullong"></a><p>
If you need a non-empty string if the text object is empty, or if the text
contents is actually a number or a boolean that is stored as a string, you
can use the following accessors:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">as_string</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">def</span> <span class="special">=</span> <span class="string">""</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">as_int</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">as_uint</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">as_double</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">float</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">as_float</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">as_bool</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">def</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">as_llong</span><span class="special">(</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">as_ullong</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">def</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
All of the above functions have the same semantics as similar <code class="computeroutput"><span class="identifier">xml_attribute</span></code> members: they return the
default argument if the text object is empty, they convert the text contents
to a target type using the same rules and restrictions. You can <a class="link" href="access.html#xml_attribute::as_int">refer
to documentation for the attribute functions</a> for details.
</p>
<a name="xml_text::data"></a><p>
<code class="computeroutput"><span class="identifier">xml_text</span></code> is essentially a
helper class that operates on <code class="computeroutput"><span class="identifier">xml_node</span></code>
values. It is bound to a node of type <a class="link" href="dom.html#node_pcdata">node_pcdata</a>
or <a class="link" href="dom.html#node_cdata">node_cdata</a>. You can use the following
function to retrieve this node:
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">data</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
Essentially, assuming <code class="computeroutput"><span class="identifier">text</span></code>
is an <code class="computeroutput"><span class="identifier">xml_text</span></code> object, calling
<code class="computeroutput"><span class="identifier">text</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span></code> is
equivalent to calling <code class="computeroutput"><span class="identifier">text</span><span class="special">.</span><span class="identifier">data</span><span class="special">().</span><span class="identifier">value</span><span class="special">()</span></code>.
</p>
<p>
This is an example of using <code class="computeroutput"><span class="identifier">xml_text</span></code>
object (<a href="../samples/text.cpp" target="_top">samples/text.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Project name: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">project</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"name"</span><span class="special">).</span><span class="identifier">text</span><span class="special">().</span><span class="identifier">get</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Project version: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">project</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"version"</span><span class="special">).</span><span class="identifier">text</span><span class="special">().</span><span class="identifier">as_double</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Project visibility: "</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">project</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"public"</span><span class="special">).</span><span class="identifier">text</span><span class="special">().</span><span class="identifier">as_bool</span><span class="special">(/*</span> <span class="identifier">def</span><span class="special">=</span> <span class="special">*/</span> <span class="keyword">true</span><span class="special">)</span> <span class="special">?</span> <span class="string">"public"</span> <span class="special">:</span> <span class="string">"private"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Project description: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">project</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"description"</span><span class="special">).</span><span class="identifier">text</span><span class="special">().</span><span class="identifier">get</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.access.misc"></a><a class="link" href="access.html#manual.access.misc" title="Miscellaneous functions"> Miscellaneous functions</a>
</h3></div></div></div>
<a name="xml_node::root"></a><p>
If you need to get the document root of some node, you can use the following
function:
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">root</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
This function returns the node with type <a class="link" href="dom.html#node_document">node_document</a>,
which is the root node of the document the node belongs to (unless the node
is null, in which case null node is returned).
</p>
<a name="xml_node::path"></a><a name="xml_node::first_element_by_path"></a><p>
While pugixml supports complex XPath expressions, sometimes a simple path
handling facility is needed. There are two functions, for getting node path
and for converting path to a node:
</p>
<pre class="programlisting"><span class="identifier">string_t</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">path</span><span class="special">(</span><span class="identifier">char_t</span> <span class="identifier">delimiter</span> <span class="special">=</span> <span class="char">'/'</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">first_element_by_path</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">path</span><span class="special">,</span> <span class="identifier">char_t</span> <span class="identifier">delimiter</span> <span class="special">=</span> <span class="char">'/'</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
Node paths consist of node names, separated with a delimiter (which is <code class="computeroutput"><span class="special">/</span></code> by default); also paths can contain self
(<code class="computeroutput"><span class="special">.</span></code>) and parent (<code class="computeroutput"><span class="special">..</span></code>) pseudo-names, so that this is a valid
path: <code class="computeroutput"><span class="string">"../../foo/./bar"</span></code>.
<code class="computeroutput"><span class="identifier">path</span></code> returns the path to
the node from the document root, <code class="computeroutput"><span class="identifier">first_element_by_path</span></code>
looks for a node represented by a given path; a path can be an absolute one
(absolute paths start with the delimiter), in which case the rest of the
path is treated as document root relative, and relative to the given node.
For example, in the following document: <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">a</span><span class="special">&gt;&lt;</span><span class="identifier">b</span><span class="special">&gt;&lt;</span><span class="identifier">c</span><span class="special">/&gt;&lt;/</span><span class="identifier">b</span><span class="special">&gt;&lt;/</span><span class="identifier">a</span><span class="special">&gt;</span></code>,
node <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">c</span><span class="special">/&gt;</span></code> has path <code class="computeroutput"><span class="string">"a/b/c"</span></code>;
calling <code class="computeroutput"><span class="identifier">first_element_by_path</span></code>
for document with path <code class="computeroutput"><span class="string">"a/b"</span></code>
results in node <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">b</span><span class="special">/&gt;</span></code>; calling <code class="computeroutput"><span class="identifier">first_element_by_path</span></code>
for node <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">a</span><span class="special">/&gt;</span></code> with path <code class="computeroutput"><span class="string">"../a/./b/../."</span></code>
results in node <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">a</span><span class="special">/&gt;</span></code>; calling <code class="computeroutput"><span class="identifier">first_element_by_path</span></code>
with path <code class="computeroutput"><span class="string">"/a"</span></code> results
in node <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">a</span><span class="special">/&gt;</span></code> for any node.
</p>
<p>
In case path component is ambiguous (if there are two nodes with given name),
the first one is selected; paths are not guaranteed to uniquely identify
nodes in a document. If any component of a path is not found, the result
of <code class="computeroutput"><span class="identifier">first_element_by_path</span></code>
is null node; also <code class="computeroutput"><span class="identifier">first_element_by_path</span></code>
returns null node for null nodes, in which case the path does not matter.
<code class="computeroutput"><span class="identifier">path</span></code> returns an empty string
for null nodes.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><span class="identifier">path</span></code> function returns the
result as STL string, and thus is not available if <a class="link" href="install.html#PUGIXML_NO_STL">PUGIXML_NO_STL</a>
is defined.
</p></td></tr>
</table></div>
<a name="xml_node::offset_debug"></a><p>
pugixml does not record row/column information for nodes upon parsing for
efficiency reasons. However, if the node has not changed in a significant
way since parsing (the name/value are not changed, and the node itself is
the original one, i.e. it was not deleted from the tree and re-added later),
it is possible to get the offset from the beginning of XML buffer:
</p>
<pre class="programlisting"><span class="identifier">ptrdiff_t</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">offset_debug</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
If the offset is not available (this happens if the node is null, was not
originally parsed from a stream, or has changed in a significant way), the
function returns -1. Otherwise it returns the offset to node's data from
the beginning of XML buffer in <a class="link" href="dom.html#char_t">pugi::char_t</a>
units. For more information on parsing offsets, see <a class="link" href="loading.html#xml_parse_result::offset">parsing
error handling documentation</a>.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <b>Accessing</b> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="loading.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="modify.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
</body>
</html>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,732 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Document object model</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="install.html" title="Installation">
<link rel="next" href="loading.html" title="Loading document">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<b>Object model</b> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="install.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="loading.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.dom"></a><a class="link" href="dom.html" title="Document object model"> Document object model</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="dom.html#manual.dom.tree"> Tree structure</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.cpp"> C++ interface</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.unicode"> Unicode interface</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.thread"> Thread-safety guarantees</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.exception"> Exception guarantees</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.memory"> Memory management</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="dom.html#manual.dom.memory.custom"> Custom memory allocation/deallocation
functions</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.memory.tuning"> Memory consumption tuning</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.memory.internals"> Document memory management
internals</a></span></dt>
</dl></dd>
</dl></div>
<p>
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 a character stream (file, string, C++ I/O stream), then traversed
with the 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>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.dom.tree"></a><a class="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 <a class="link" href="dom.html#xml_document">xml_document</a>.
Document has one or more child nodes, which correspond to C++ type <a class="link" href="dom.html#xml_node">xml_node</a>. 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 <a class="link" href="dom.html#xml_attribute">xml_attribute</a>,
and some additional data (i.e. name).
</p>
<a name="xml_node_type"></a><p>
The tree nodes can be of one of the following types (which together form
the enumeration <code class="computeroutput"><span class="identifier">xml_node_type</span></code>):
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Document node (<a name="node_document"></a><code class="literal">node_document</code>) - this
is the root of the tree, which consists of several child nodes. This
node corresponds to <a class="link" href="dom.html#xml_document">xml_document</a>
class; note that <a class="link" href="dom.html#xml_document">xml_document</a> is
a sub-class of <a class="link" href="dom.html#xml_node">xml_node</a>, so the entire
node interface is also available. However, document node is special in
several ways, which are covered below. There can be only one document
node in the tree; document node does not have any XML representation.
<br><br>
</li>
<li class="listitem">
Element/tag node (<a name="node_element"></a><code class="literal">node_element</code>) - 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:
</li>
</ul></div>
<pre class="programlisting"><span class="special">&lt;</span><span class="identifier">node</span> <span class="identifier">attr</span><span class="special">=</span><span class="string">"value"</span><span class="special">&gt;&lt;</span><span class="identifier">child</span><span class="special">/&gt;&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span>
</pre>
<div class="blockquote"><blockquote class="blockquote"><p>
There are two element nodes here: one has name <code class="computeroutput"><span class="string">"node"</span></code>,
single attribute <code class="computeroutput"><span class="string">"attr"</span></code>
and single child <code class="computeroutput"><span class="string">"child"</span></code>,
another has name <code class="computeroutput"><span class="string">"child"</span></code>
and does not have any attributes or child nodes.
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Plain character data nodes (<a name="node_pcdata"></a><code class="literal">node_pcdata</code>)
represent plain text in XML. PCDATA nodes have a value, but do not have
a name or children/attributes. Note that <span class="bold"><strong>plain
character data is not a part of the element node but instead has its
own node</strong></span>; an element node can have several child PCDATA nodes.
The example XML representation of text nodes is as follows:
</li></ul></div>
<pre class="programlisting"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;</span> <span class="identifier">text1</span> <span class="special">&lt;</span><span class="identifier">child</span><span class="special">/&gt;</span> <span class="identifier">text2</span> <span class="special">&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span>
</pre>
<div class="blockquote"><blockquote class="blockquote"><p>
Here <code class="computeroutput"><span class="string">"node"</span></code> element
has three children, two of which are PCDATA nodes with values <code class="computeroutput"><span class="string">" text1 "</span></code> and <code class="computeroutput"><span class="string">"
text2 "</span></code>.
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Character data nodes (<a name="node_cdata"></a><code class="literal">node_cdata</code>) 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:
</li></ul></div>
<pre class="programlisting"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;</span> <span class="special">&lt;![</span><span class="identifier">CDATA</span><span class="special">[[</span><span class="identifier">text1</span><span class="special">]]&gt;</span> <span class="special">&lt;</span><span class="identifier">child</span><span class="special">/&gt;</span> <span class="special">&lt;![</span><span class="identifier">CDATA</span><span class="special">[[</span><span class="identifier">text2</span><span class="special">]]&gt;</span> <span class="special">&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span>
</pre>
<div class="blockquote"><blockquote class="blockquote"><p>
CDATA nodes make it easy to include non-escaped &lt;, &amp; and &gt; characters
in plain text. CDATA value can not contain the character sequence ]]&gt;,
since it is used to determine the end of node contents.
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Comment nodes (<a name="node_comment"></a><code class="literal">node_comment</code>) 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:
</li></ul></div>
<pre class="programlisting"><span class="special">&lt;!--</span> <span class="identifier">comment</span> <span class="identifier">text</span> <span class="special">--&gt;</span>
</pre>
<div class="blockquote"><blockquote class="blockquote"><p>
Here the comment node has value <code class="computeroutput"><span class="string">"comment
text"</span></code>. By default comment nodes are treated as non-essential
part of XML markup and are not loaded during XML parsing. You can override
this behavior with <a class="link" href="loading.html#parse_comments">parse_comments</a>
flag.
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Processing instruction node (<a name="node_pi"></a><code class="literal">node_pi</code>) 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:
</li></ul></div>
<pre class="programlisting"><span class="special">&lt;?</span><span class="identifier">name</span> <span class="identifier">value</span><span class="special">?&gt;</span>
</pre>
<div class="blockquote"><blockquote class="blockquote"><p>
Here the name (also called PI target) is <code class="computeroutput"><span class="string">"name"</span></code>,
and the value is <code class="computeroutput"><span class="string">"value"</span></code>.
By default PI nodes are treated as non-essential part of XML markup and
are not loaded during XML parsing. You can override this behavior with
<a class="link" href="loading.html#parse_pi">parse_pi</a> flag.
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Declaration node (<a name="node_declaration"></a><code class="literal">node_declaration</code>)
represents document declarations in XML. Declaration nodes have a name
(<code class="computeroutput"><span class="string">"xml"</span></code>) 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:
</li></ul></div>
<pre class="programlisting"><span class="special">&lt;?</span><span class="identifier">xml</span> <span class="identifier">version</span><span class="special">=</span><span class="string">"1.0"</span><span class="special">?&gt;</span>
</pre>
<div class="blockquote"><blockquote class="blockquote"><p>
Here the node has name <code class="computeroutput"><span class="string">"xml"</span></code>
and a single attribute with name <code class="computeroutput"><span class="string">"version"</span></code>
and value <code class="computeroutput"><span class="string">"1.0"</span></code>.
By default declaration nodes are treated as non-essential part of XML markup
and are not loaded during XML parsing. You can override this behavior with
<a class="link" href="loading.html#parse_declaration">parse_declaration</a> flag. Also,
by default a dummy declaration is output when XML document is saved unless
there is already a declaration in the document; you can disable this with
<a class="link" href="saving.html#format_no_declaration">format_no_declaration</a> flag.
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Document type declaration node (<a name="node_doctype"></a><code class="literal">node_doctype</code>)
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 <code class="computeroutput"><span class="special">&lt;!</span><span class="identifier">ENTITY</span><span class="special">&gt;</span></code>. 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:
</li></ul></div>
<pre class="programlisting"><span class="special">&lt;!</span><span class="identifier">DOCTYPE</span> <span class="identifier">greeting</span> <span class="special">[</span> <span class="special">&lt;!</span><span class="identifier">ELEMENT</span> <span class="identifier">greeting</span> <span class="special">(</span><span class="preprocessor">#PCDATA</span><span class="special">)&gt;</span> <span class="special">]&gt;</span>
</pre>
<div class="blockquote"><blockquote class="blockquote"><p>
Here the node has value <code class="computeroutput"><span class="string">"greeting [ &lt;!ELEMENT
greeting (#PCDATA)&gt; ]"</span></code>. By default document type
declaration nodes are treated as non-essential part of XML markup and are
not loaded during XML parsing. You can override this behavior with <a class="link" href="loading.html#parse_doctype">parse_doctype</a> flag.
</p></blockquote></div>
<p>
Finally, here is a complete example of XML document and the corresponding
tree representation (<a href="../samples/tree.xml" target="_top">samples/tree.xml</a>):
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<tbody><tr>
<td>
<p>
</p>
<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="special">&lt;?</span><span class="identifier">xml</span> <span class="identifier">version</span><span class="special">=</span><span class="string">"1.0"</span><span class="special">?&gt;</span>
<span class="special">&lt;</span><span class="identifier">mesh</span> <span class="identifier">name</span><span class="special">=</span><span class="string">"mesh_root"</span><span class="special">&gt;</span>
<span class="special">&lt;!--</span> <span class="identifier">here</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">mesh</span> <span class="identifier">node</span> <span class="special">--&gt;</span>
<span class="identifier">some</span> <span class="identifier">text</span>
<span class="special">&lt;![</span><span class="identifier">CDATA</span><span class="special">[</span><span class="identifier">someothertext</span><span class="special">]]&gt;</span>
<span class="identifier">some</span> <span class="identifier">more</span> <span class="identifier">text</span>
<span class="special">&lt;</span><span class="identifier">node</span> <span class="identifier">attr1</span><span class="special">=</span><span class="string">"value1"</span> <span class="identifier">attr2</span><span class="special">=</span><span class="string">"value2"</span> <span class="special">/&gt;</span>
<span class="special">&lt;</span><span class="identifier">node</span> <span class="identifier">attr1</span><span class="special">=</span><span class="string">"value2"</span><span class="special">&gt;</span>
<span class="special">&lt;</span><span class="identifier">innernode</span><span class="special">/&gt;</span>
<span class="special">&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span>
<span class="special">&lt;/</span><span class="identifier">mesh</span><span class="special">&gt;</span>
<span class="special">&lt;?</span><span class="identifier">include</span> <span class="identifier">somedata</span><span class="special">?&gt;</span>
</pre>
<p>
</p>
</td>
<td>
<p>
<a href="../images/dom_tree.png" target="_top"><span class="inlinemediaobject"><img src="../images/dom_tree_thumb.png" alt="dom_tree_thumb"></span></a>
</p>
</td>
</tr></tbody>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.dom.cpp"></a><a class="link" href="dom.html#manual.dom.cpp" title="C++ interface"> C++ interface</a>
</h3></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
All pugixml classes and functions are located in the <code class="computeroutput"><span class="identifier">pugi</span></code>
namespace; you have to either use explicit name qualification (i.e. <code class="computeroutput"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span></code>), or to gain access to relevant
symbols via <code class="computeroutput"><span class="keyword">using</span></code> directive
(i.e. <code class="computeroutput"><span class="keyword">using</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span><span class="special">;</span></code> or <code class="computeroutput"><span class="keyword">using</span>
<span class="keyword">namespace</span> <span class="identifier">pugi</span><span class="special">;</span></code>). The namespace will be omitted from all
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++ classes representing the tree (<code class="computeroutput"><span class="identifier">xml_document</span></code>,
<code class="computeroutput"><span class="identifier">xml_node</span></code>, <code class="computeroutput"><span class="identifier">xml_attribute</span></code>);
some operations on <code class="computeroutput"><span class="identifier">xml_node</span></code>
are only valid for certain node types. The classes are described below.
</p>
<a name="xml_document"></a><a name="xml_document::document_element"></a><p>
<code class="computeroutput"><span class="identifier">xml_document</span></code> is the owner
of the entire document structure; it is a non-copyable class. The interface
of <code class="computeroutput"><span class="identifier">xml_document</span></code> consists
of loading functions (see <a class="xref" href="loading.html" title="Loading document"> Loading document</a>), saving functions (see <a class="xref" href="saving.html" title="Saving document"> Saving document</a>)
and the entire interface of <code class="computeroutput"><span class="identifier">xml_node</span></code>,
which allows for document inspection and/or modification. Note that while
<code class="computeroutput"><span class="identifier">xml_document</span></code> is a sub-class
of <code class="computeroutput"><span class="identifier">xml_node</span></code>, <code class="computeroutput"><span class="identifier">xml_node</span></code> is not a polymorphic type; the
inheritance is present only to simplify usage. Alternatively you can use
the <code class="computeroutput"><span class="identifier">document_element</span></code> function
to get the element node that's the immediate child of the document.
</p>
<a name="xml_document::ctor"></a><a name="xml_document::dtor"></a><a name="xml_document::reset"></a><p>
Default constructor of <code class="computeroutput"><span class="identifier">xml_document</span></code>
initializes the document to the tree with only a root node (document node).
You can then populate it with data using either tree modification functions
or loading functions; all loading functions destroy the previous tree with
all occupied memory, which puts existing node/attribute handles for this
document to invalid state. If you want to destroy the previous tree, you
can use the <code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">reset</span></code>
function; it destroys the tree and replaces it with either an empty one or
a copy of the specified document. Destructor of <code class="computeroutput"><span class="identifier">xml_document</span></code>
also destroys the tree, thus the lifetime of the document object should exceed
the lifetimes of any node/attribute handles that point to the tree.
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
While technically node/attribute handles can be alive when the tree they're
referring to is destroyed, calling any member function for these handles
results in undefined behavior. Thus it is recommended to make sure that
the document is destroyed only after all references to its nodes/attributes
are destroyed.
</p></td></tr>
</table></div>
<a name="xml_node"></a><a name="xml_node::type"></a><p>
<code class="computeroutput"><span class="identifier">xml_node</span></code> is the handle to
document node; it can point to any node in the document, including the document
node itself. There is a common interface for nodes of all types; the actual
<a class="link" href="dom.html#xml_node_type">node type</a> can be queried via the <code class="computeroutput"><span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">type</span><span class="special">()</span></code>
method. Note that <code class="computeroutput"><span class="identifier">xml_node</span></code>
is only a handle to the actual node, not the node itself - you can have several
<code class="computeroutput"><span class="identifier">xml_node</span></code> handles pointing
to the same underlying object. Destroying <code class="computeroutput"><span class="identifier">xml_node</span></code>
handle does not destroy the node and does not remove it from the tree. The
size of <code class="computeroutput"><span class="identifier">xml_node</span></code> is equal
to that of a pointer, so it is nothing more than a lightweight wrapper around
a pointer; you can safely pass or return <code class="computeroutput"><span class="identifier">xml_node</span></code>
objects by value without additional overhead.
</p>
<a name="node_null"></a><p>
There is a special value of <code class="computeroutput"><span class="identifier">xml_node</span></code>
type, known as null node or empty node (such nodes have type <code class="computeroutput"><span class="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: <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">parent</span><span class="special">().</span><span class="identifier">parent</span><span class="special">()</span></code>; if a node is a null node or it does not
have a parent, the first <code class="computeroutput"><span class="identifier">parent</span><span class="special">()</span></code> call returns null node; the second <code class="computeroutput"><span class="identifier">parent</span><span class="special">()</span></code>
call then also returns null node, which makes error handling easier.
</p>
<a name="xml_attribute"></a><p>
<code class="computeroutput"><span class="identifier">xml_attribute</span></code> is the handle
to an XML attribute; it has the same semantics as <code class="computeroutput"><span class="identifier">xml_node</span></code>,
i.e. there can be several <code class="computeroutput"><span class="identifier">xml_attribute</span></code>
handles pointing to the same underlying object and there is a special null
attribute value, which propagates to function results.
</p>
<a name="xml_attribute::ctor"></a><a name="xml_node::ctor"></a><p>
Both <code class="computeroutput"><span class="identifier">xml_node</span></code> and <code class="computeroutput"><span class="identifier">xml_attribute</span></code> have the default constructor
which initializes them to null objects.
</p>
<a name="xml_attribute::comparison"></a><a name="xml_node::comparison"></a><p>
<code class="computeroutput"><span class="identifier">xml_node</span></code> and <code class="computeroutput"><span class="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 in 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 in any other way. Do not use relational comparison
operators except for search optimization (i.e. associative container keys).
</p>
<a name="xml_attribute::hash_value"></a><a name="xml_node::hash_value"></a><p>
If you want to use <code class="computeroutput"><span class="identifier">xml_node</span></code>
or <code class="computeroutput"><span class="identifier">xml_attribute</span></code> objects
as keys in hash-based associative containers, you can use the <code class="computeroutput"><span class="identifier">hash_value</span></code> member functions. They return
the hash values that are guaranteed to be the same for all handles to the
same underlying object. The hash value for null handles is 0.
</p>
<a name="xml_attribute::unspecified_bool_type"></a><a name="xml_node::unspecified_bool_type"></a><a name="xml_attribute::empty"></a><a name="xml_node::empty"></a><p>
Finally handles can be implicitly cast to boolean-like objects, so that you
can test if the node/attribute is empty with the following code: <code class="computeroutput"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">node</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span>
<span class="special">}</span></code> or <code class="computeroutput"><span class="keyword">if</span>
<span class="special">(!</span><span class="identifier">node</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span>
<span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>.
Alternatively you can check if a given <code class="computeroutput"><span class="identifier">xml_node</span></code>/<code class="computeroutput"><span class="identifier">xml_attribute</span></code> handle is null by calling
the following methods:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">empty</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">empty</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
Nodes and attributes do not exist without a 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 <a class="link" href="modify.html#xml_node::remove_child">xml_node::remove_child</a>)
or removing an attribute invalidates the corresponding handles. There is
no way to check handle validity; you have to ensure correctness through external
mechanisms.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.dom.unicode"></a><a class="link" href="dom.html#manual.dom.unicode" title="Unicode interface"> Unicode interface</a>
</h3></div></div></div>
<p>
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 <a class="link" href="install.html#PUGIXML_WCHAR_MODE">PUGIXML_WCHAR_MODE</a>
define; you can set it via <code class="filename">pugiconfig.hpp</code> or via preprocessor options, as
discussed in <a class="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 the size of <code class="computeroutput"><span class="keyword">wchar_t</span></code>
type.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
If the size of <code class="computeroutput"><span class="keyword">wchar_t</span></code> is
2, pugixml assumes UTF-16 encoding instead of UCS-2, which means that some
characters are represented as two code points.
</p></td></tr>
</table></div>
<p>
All tree functions that work with strings work with either C-style null terminated
strings or STL strings of the selected character type. For example, node
name accessors look like this in char mode:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">set_name</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">value</span><span class="special">);</span>
</pre>
<p>
and like this in wchar_t mode:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">set_name</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">value</span><span class="special">);</span>
</pre>
<a name="char_t"></a><a name="string_t"></a><p>
There is a special type, <code class="computeroutput"><span class="identifier">pugi</span><span class="special">::</span><span class="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
<code class="computeroutput"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">string_t</span></code>, which is defined as the STL string
of the character type; it corresponds to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
in char mode and to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span></code> in wchar_t mode.
</p>
<p>
In addition to the interface, the internal implementation changes to store
XML data as <code class="computeroutput"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">char_t</span></code>; this means that these two modes
have different memory usage characteristics. The conversion to <code class="computeroutput"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">char_t</span></code> upon document loading and from
<code class="computeroutput"><span class="identifier">pugi</span><span class="special">::</span><span class="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 non-ASCII, wchar_t mode
is probably a better choice.
</p>
<a name="as_utf8"></a><a name="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:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">as_utf8</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">str</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span> <span class="identifier">as_wide</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">str</span><span class="special">);</span>
</pre>
<p>
Both functions accept a null-terminated string as an argument <code class="computeroutput"><span class="identifier">str</span></code>, and return the converted string.
<code class="computeroutput"><span class="identifier">as_utf8</span></code> performs conversion
from UTF-16/32 to UTF-8; <code class="computeroutput"><span class="identifier">as_wide</span></code>
performs conversion from UTF-8 to UTF-16/32. Invalid UTF sequences are silently
discarded upon conversion. <code class="computeroutput"><span class="identifier">str</span></code>
has to be a valid string; passing null pointer results in undefined behavior.
There are also two overloads with the same semantics which accept a string
as an argument:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">as_utf8</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span><span class="special">&amp;</span> <span class="identifier">str</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span> <span class="identifier">as_wide</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&amp;</span> <span class="identifier">str</span><span class="special">);</span>
</pre>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top">
<p>
Most examples in this documentation assume char interface and therefore
will not compile with <a class="link" href="install.html#PUGIXML_WCHAR_MODE">PUGIXML_WCHAR_MODE</a>.
This is done to simplify the documentation; usually the only changes you'll
have to make is to pass <code class="computeroutput"><span class="keyword">wchar_t</span></code>
string literals, i.e. instead of
</p>
<p>
<code class="computeroutput"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span>
<span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"bookstore"</span><span class="special">).</span><span class="identifier">find_child_by_attribute</span><span class="special">(</span><span class="string">"book"</span><span class="special">,</span> <span class="string">"id"</span><span class="special">,</span> <span class="string">"12345"</span><span class="special">);</span></code>
</p>
<p>
you'll have to do
</p>
<p>
<code class="computeroutput"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span>
<span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="identifier">L</span><span class="string">"bookstore"</span><span class="special">).</span><span class="identifier">find_child_by_attribute</span><span class="special">(</span><span class="identifier">L</span><span class="string">"book"</span><span class="special">,</span> <span class="identifier">L</span><span class="string">"id"</span><span class="special">,</span> <span class="identifier">L</span><span class="string">"12345"</span><span class="special">);</span></code>
</p>
</td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.dom.thread"></a><a class="link" href="dom.html#manual.dom.thread" title="Thread-safety guarantees"> Thread-safety guarantees</a>
</h3></div></div></div>
<p>
Almost all functions in pugixml have the following thread-safety guarantees:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
it is safe to call free (non-member) functions from multiple threads
</li>
<li class="listitem">
it is safe to perform concurrent read-only accesses to the same tree
(all constant member functions do not modify the tree)
</li>
<li class="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 <a class="link" href="dom.html#set_memory_management_functions">set_memory_management_functions</a>;
it modifies global variables and as such is not thread-safe. Its usage policy
has more restrictions, see <a class="xref" href="dom.html#manual.dom.memory.custom" title="Custom memory allocation/deallocation functions"> Custom memory allocation/deallocation
functions</a>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.dom.exception"></a><a class="link" href="dom.html#manual.dom.exception" title="Exception guarantees"> Exception guarantees</a>
</h3></div></div></div>
<p>
With the exception of XPath, pugixml itself does not throw any exceptions.
Additionally, most pugixml functions have a no-throw exception guarantee.
</p>
<p>
This is not applicable to functions that operate on STL strings or IOstreams;
such functions have either strong guarantee (functions that operate on strings)
or basic guarantee (functions that operate on streams). Also functions that
call user-defined callbacks (i.e. <a class="link" href="access.html#xml_node::traverse">xml_node::traverse</a>
or <a class="link" href="access.html#xml_node::find_node">xml_node::find_node</a>) do not
provide any exception guarantees beyond the ones provided by the callback.
</p>
<p>
If exception handling is not disabled with <a class="link" href="install.html#PUGIXML_NO_EXCEPTIONS">PUGIXML_NO_EXCEPTIONS</a>
define, XPath functions may throw <a class="link" href="xpath.html#xpath_exception">xpath_exception</a>
on parsing errors; also, XPath functions may throw <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code>
in low memory conditions. Still, XPath functions provide strong exception
guarantee.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.dom.memory"></a><a class="link" href="dom.html#manual.dom.memory" title="Memory management"> Memory management</a>
</h3></div></div></div>
<p>
pugixml requests the memory needed for document storage in big chunks, and
allocates document data inside those chunks. This section discusses replacing
functions used for chunk allocation and internal memory management implementation.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.dom.memory.custom"></a><a class="link" href="dom.html#manual.dom.memory.custom" title="Custom memory allocation/deallocation functions"> Custom memory allocation/deallocation
functions</a>
</h4></div></div></div>
<a name="allocation_function"></a><a name="deallocation_function"></a><p>
All memory for tree structure, tree data and XPath objects is allocated
via globally specified functions, which default to malloc/free. You can
set your own allocation functions with set_memory_management function.
The function interfaces are the same as that of malloc/free:
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="keyword">void</span><span class="special">*</span> <span class="special">(*</span><span class="identifier">allocation_function</span><span class="special">)(</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">);</span>
<span class="keyword">typedef</span> <span class="keyword">void</span> <span class="special">(*</span><span class="identifier">deallocation_function</span><span class="special">)(</span><span class="keyword">void</span><span class="special">*</span> <span class="identifier">ptr</span><span class="special">);</span>
</pre>
<a name="set_memory_management_functions"></a><a name="get_memory_allocation_function"></a><a name="get_memory_deallocation_function"></a><p>
You can use the following accessor functions to change or get current memory
management functions:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">set_memory_management_functions</span><span class="special">(</span><span class="identifier">allocation_function</span> <span class="identifier">allocate</span><span class="special">,</span> <span class="identifier">deallocation_function</span> <span class="identifier">deallocate</span><span class="special">);</span>
<span class="identifier">allocation_function</span> <span class="identifier">get_memory_allocation_function</span><span class="special">();</span>
<span class="identifier">deallocation_function</span> <span class="identifier">get_memory_deallocation_function</span><span class="special">();</span>
</pre>
<p>
Allocation function is called with the size (in bytes) as an argument and
should return a pointer to a memory block with alignment that is suitable
for storage of primitive types (usually a maximum of <code class="computeroutput"><span class="keyword">void</span><span class="special">*</span></code> and <code class="computeroutput"><span class="keyword">double</span></code>
types alignment is sufficient) and size that is greater than 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).
</p>
<p>
Deallocation function is called with the pointer that was returned by some
call to allocation function; it is never called with a null pointer. 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 (<a href="../samples/custom_memory_management.cpp" target="_top">samples/custom_memory_management.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">void</span><span class="special">*</span> <span class="identifier">custom_allocate</span><span class="special">(</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="keyword">new</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">nothrow</span><span class="special">)</span> <span class="keyword">char</span><span class="special">[</span><span class="identifier">size</span><span class="special">];</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">custom_deallocate</span><span class="special">(</span><span class="keyword">void</span><span class="special">*</span> <span class="identifier">ptr</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">delete</span><span class="special">[]</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">ptr</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">set_memory_management_functions</span><span class="special">(</span><span class="identifier">custom_allocate</span><span class="special">,</span> <span class="identifier">custom_deallocate</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
When setting new memory management functions, care must be taken to make
sure that there are no live pugixml objects. Otherwise when the objects
are destroyed, the new deallocation function will be called with the memory
obtained by the old allocation function, resulting in undefined behavior.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.dom.memory.tuning"></a><a class="link" href="dom.html#manual.dom.memory.tuning" title="Memory consumption tuning"> Memory consumption tuning</a>
</h4></div></div></div>
<p>
There are several important buffering optimizations in pugixml that rely
on predefined constants. These constants have default values that were
tuned for common usage patterns; for some applications, changing these
constants might improve memory consumption or increase performance. Changing
these constants is not recommended unless their default values result in
visible problems.
</p>
<p>
These constants can be tuned via configuration defines, as discussed in
<a class="xref" href="install.html#manual.install.building.config" title="Additional configuration options"> Additional configuration
options</a>; it is recommended to set them in <code class="filename">pugiconfig.hpp</code>.
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">PUGIXML_MEMORY_PAGE_SIZE</span></code>
controls the page size for document memory allocation. Memory for node/attribute
objects is allocated in pages of the specified size. The default size
is 32 Kb; for some applications the size is too large (i.e. embedded
systems with little heap space or applications that keep lots of XML
documents in memory). A minimum size of 1 Kb is recommended. <br><br>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">PUGIXML_MEMORY_OUTPUT_STACK</span></code>
controls the cumulative stack space required to output the node. Any
output operation (i.e. saving a subtree to file) uses an internal buffering
scheme for performance reasons. The default size is 10 Kb; if you're
using node output from threads with little stack space, decreasing
this value can prevent stack overflows. A minimum size of 1 Kb is recommended.
<br><br>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">PUGIXML_MEMORY_XPATH_PAGE_SIZE</span></code>
controls the page size for XPath memory allocation. Memory for XPath
query objects as well as internal memory for XPath evaluation is allocated
in pages of the specified size. The default size is 4 Kb; if you have
a lot of resident XPath query objects, you might need to decrease the
size to improve memory consumption. A minimum size of 256 bytes is
recommended.
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.dom.memory.internals"></a><a class="link" href="dom.html#manual.dom.memory.internals" title="Document memory management internals"> Document memory management
internals</a>
</h4></div></div></div>
<p>
Constructing a document object using the default constructor does not result
in any allocations; document node is stored inside the <a class="link" href="dom.html#xml_document">xml_document</a>
object.
</p>
<p>
When the document is loaded from file/buffer, unless an inplace loading
function is used (see <a class="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 <a class="link" href="dom.html#xml_document">xml_document</a> 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
allocation meta-data is very small in size.
</p>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<b>Object model</b> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="install.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="loading.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
</body>
</html>

View file

@ -1,517 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Installation</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="../manual.html" title="pugixml 1.6">
<link rel="next" href="dom.html" title="Document object model">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<b>Installation</b> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="../manual.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="dom.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.install"></a><a class="link" href="install.html" title="Installation"> Installation</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="install.html#manual.install.getting"> Getting pugixml</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="install.html#manual.install.getting.source"> Source distributions</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.getting.git"> Git repository</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.getting.subversion"> Subversion repository</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="install.html#manual.install.building"> Building pugixml</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="install.html#manual.install.building.embed"> Building pugixml as
a part of another static library/executable</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.building.static"> Building pugixml as
a standalone static library</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.building.shared"> Building pugixml as
a standalone shared library</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.building.header"> Using pugixml in header-only
mode</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.building.config"> Additional configuration
options</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="install.html#manual.install.portability"> Portability</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.install.getting"></a><a class="link" href="install.html#manual.install.getting" title="Getting pugixml"> Getting pugixml</a>
</h3></div></div></div>
<p>
pugixml is distributed in source form. You can either download a source distribution
or clone the Git repository.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.install.getting.source"></a><a class="link" href="install.html#manual.install.getting.source" title="Source distributions"> Source distributions</a>
</h4></div></div></div>
<p>
You can download the latest source distribution via one of the following
links:
</p>
<pre class="programlisting"><a href="https://github.com/zeux/pugixml/releases/download/v1.6/pugixml-1.6.zip" target="_top">https://github.com/zeux/pugixml/releases/download/v1.6/pugixml-1.6.zip</a>
<a href="https://github.com/zeux/pugixml/releases/download/v1.6/pugixml-1.6.tar.gz" target="_top">https://github.com/zeux/pugixml/releases/download/v1.6/pugixml-1.6.tar.gz</a>
</pre>
<p>
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. The files have different line endings depending on the archive
format - <code class="filename">.zip</code> archive has Windows line endings, <code class="filename">.tar.gz</code> archive has Unix
line endings. Otherwise the files in both archives are identical.
</p>
<p>
If you need an older version, you can download it from the <a href="https://github.com/zeux/pugixml/releases" target="_top">version
archive</a>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.install.getting.git"></a><a class="link" href="install.html#manual.install.getting.git" title="Git repository"> Git repository</a>
</h4></div></div></div>
<p>
The Git repository is located at <a href="https://github.com/zeux/pugixml/" target="_top">https://github.com/zeux/pugixml/</a>.
There is a Git tag "v{version}" for each version; also there
is the "latest" tag, which always points to the latest stable
release.
</p>
<p>
For example, to checkout the current version, you can use this command:
</p>
<pre class="programlisting">git clone https://github.com/zeux/pugixml
cd pugixml
git checkout v1.6
</pre>
<p>
The repository contains library source, documentation, code examples and
full unit test suite.
</p>
<p>
Use latest version tag if you want to automatically get new versions. Use
other tags if you want to switch to new versions only explicitly. Also
please note that the master branch contains the work-in-progress version
of the code; while this means that you can get new features and bug fixes
from master without waiting for a new release, this also means that occasionally
the code can be broken in some configurations.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.install.getting.subversion"></a><a class="link" href="install.html#manual.install.getting.subversion" title="Subversion repository"> Subversion repository</a>
</h4></div></div></div>
<p>
You can access the Git repository via Subversion using <a href="https://github.com/zeux/pugixml" target="_top">https://github.com/zeux/pugixml</a>
URL. For example, to checkout the current version, you can use this command:
</p>
<pre class="programlisting">svn checkout https://github.com/zeux/pugixml/tags/v1.6 pugixml</pre>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.install.building"></a><a class="link" href="install.html#manual.install.building" title="Building pugixml"> Building pugixml</a>
</h3></div></div></div>
<p>
pugixml is distributed in source form without any pre-built binaries; you
have to build them yourself.
</p>
<p>
The complete pugixml source consists of three files - one source file, <code class="filename">pugixml.cpp</code>,
and two header files, <code class="filename">pugixml.hpp</code> and <code class="filename">pugiconfig.hpp</code>. <code class="filename">pugixml.hpp</code> is the primary
header which you need to include in order to use pugixml classes/functions;
<code class="filename">pugiconfig.hpp</code> is a supplementary configuration file (see <a class="xref" href="install.html#manual.install.building.config" title="Additional configuration options"> Additional configuration
options</a>).
The rest of this guide assumes that <code class="filename">pugixml.hpp</code> is either in the current directory
or in one of include directories of your projects, so that <code class="computeroutput"><span class="preprocessor">#include</span> <span class="string">"pugixml.hpp"</span></code>
can find the header; however you can also use relative path (i.e. <code class="computeroutput"><span class="preprocessor">#include</span> <span class="string">"../libs/pugixml/src/pugixml.hpp"</span></code>)
or include directory-relative path (i.e. <code class="computeroutput"><span class="preprocessor">#include</span>
<span class="special">&lt;</span><span class="identifier">xml</span><span class="special">/</span><span class="identifier">thirdparty</span><span class="special">/</span><span class="identifier">pugixml</span><span class="special">/</span><span class="identifier">src</span><span class="special">/</span><span class="identifier">pugixml</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>).
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.install.building.embed"></a><a class="link" href="install.html#manual.install.building.embed" title="Building pugixml as a part of another static library/executable"> Building pugixml as
a part of another static library/executable</a>
</h4></div></div></div>
<p>
The easiest way to build pugixml is to compile the source file, <code class="filename">pugixml.cpp</code>,
along with the existing library/executable. This process depends on the
method of building your application; for example, if you're using Microsoft
Visual Studio<a href="#ftn.trademarks" class="footnote" name="trademarks"><sup class="footnote">[1]</sup></a>, Apple Xcode, Code::Blocks or any other IDE, just add <code class="filename">pugixml.cpp</code> to
one of your projects.
</p>
<p>
If you're using Microsoft Visual Studio and the project has precompiled
headers turned on, you'll see the following error messages:
</p>
<pre class="programlisting">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?</pre>
<p>
The correct way to resolve this is to disable precompiled headers for <code class="filename">pugixml.cpp</code>;
you have to set "Create/Use Precompiled Header" option (Properties
dialog -&gt; C/C++ -&gt; Precompiled Headers -&gt; Create/Use Precompiled
Header) to "Not Using Precompiled Headers". You'll have to do
it for all project configurations/platforms (you can select Configuration
"All Configurations" and Platform "All Platforms" before
editing the option):
</p>
<div class="informaltable"><table class="table">
<colgroup><col></colgroup>
<tbody><tr><td>
<p>
<a href="../images/vs2005_pch1.png" target="_top"><span class="inlinemediaobject"><img src="../images/vs2005_pch1_thumb.png" alt="vs2005_pch1_thumb"></span></a> <span class="inlinemediaobject"><img src="../images/next.png" alt="next"></span> <a href="../images/vs2005_pch2.png" target="_top"><span class="inlinemediaobject"><img src="../images/vs2005_pch2_thumb.png" alt="vs2005_pch2_thumb"></span></a> <span class="inlinemediaobject"><img src="../images/next.png" alt="next"></span> <a href="../images/vs2005_pch3.png" target="_top"><span class="inlinemediaobject"><img src="../images/vs2005_pch3_thumb.png" alt="vs2005_pch3_thumb"></span></a> <span class="inlinemediaobject"><img src="../images/next.png" alt="next"></span> <a href="../images/vs2005_pch4.png" target="_top"><span class="inlinemediaobject"><img src="../images/vs2005_pch4_thumb.png" alt="vs2005_pch4_thumb"></span></a>
</p>
</td></tr></tbody>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.install.building.static"></a><a class="link" href="install.html#manual.install.building.static" title="Building pugixml as a standalone static library"> Building pugixml as
a standalone static library</a>
</h4></div></div></div>
<p>
It's possible to compile pugixml as a standalone static library. This process
depends on the method of building your application; pugixml distribution
comes with project files for several popular IDEs/build systems. There
are project files for Apple XCode3, Code::Blocks, Codelite, Microsoft Visual
Studio 2005, 2008, 2010, and configuration scripts for CMake and premake4.
You're welcome to submit project files/build scripts for other software;
see <a class="xref" href="../manual.html#manual.overview.feedback" title="Feedback"> Feedback</a>.
</p>
<p>
There are two projects for each version of Microsoft Visual Studio: one
for dynamically linked CRT, which has a name like <code class="filename">pugixml_vs2008.vcproj</code>,
and another one for statically linked CRT, which has a name like <code class="filename">pugixml_vs2008_static.vcproj</code>.
You should select the version that matches the CRT used in your application;
the default option for new projects created by Microsoft Visual Studio
is dynamically linked CRT, so unless you changed the defaults, you should
use the version with dynamic CRT (i.e. <code class="filename">pugixml_vs2008.vcproj</code> for Microsoft
Visual Studio 2008).
</p>
<p>
In addition to adding pugixml project to your workspace, you'll have to
make sure that your application links with pugixml library. If you're using
Microsoft Visual Studio 2005/2008, you can add a dependency from your application
project to pugixml one. If you're using Microsoft Visual Studio 2010, you'll
have to add a reference to your application project instead. For other
IDEs/systems, consult the relevant documentation.
</p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Microsoft Visual Studio 2005/2008
</p>
</th>
<th>
<p>
Microsoft Visual Studio 2010
</p>
</th>
</tr></thead>
<tbody><tr>
<td>
<p>
<a href="../images/vs2005_link1.png" target="_top"><span class="inlinemediaobject"><img src="../images/vs2005_link1_thumb.png" alt="vs2005_link1_thumb"></span></a> <span class="inlinemediaobject"><img src="../images/next.png" alt="next"></span> <a href="../images/vs2005_link2.png" target="_top"><span class="inlinemediaobject"><img src="../images/vs2005_link2_thumb.png" alt="vs2005_link2_thumb"></span></a>
</p>
</td>
<td>
<p>
<a href="../images/vs2010_link1.png" target="_top"><span class="inlinemediaobject"><img src="../images/vs2010_link1_thumb.png" alt="vs2010_link1_thumb"></span></a> <span class="inlinemediaobject"><img src="../images/next.png" alt="next"></span> <a href="../images/vs2010_link2.png" target="_top"><span class="inlinemediaobject"><img src="../images/vs2010_link2_thumb.png" alt="vs2010_link2_thumb"></span></a>
</p>
</td>
</tr></tbody>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.install.building.shared"></a><a class="link" href="install.html#manual.install.building.shared" title="Building pugixml as a standalone shared library"> Building pugixml as
a standalone shared library</a>
</h4></div></div></div>
<p>
It's possible to compile pugixml as a standalone shared library. The process
is usually similar to the static library approach; however, no preconfigured
projects/scripts are included into pugixml distribution, so you'll have
to do it yourself. Generally, if you're using GCC-based toolchain, the
process does not differ from building any other library as DLL (adding
-shared to compilation flags should suffice); if you're using MSVC-based
toolchain, you'll have to explicitly mark exported symbols with a declspec
attribute. You can do it by defining <a class="link" href="install.html#PUGIXML_API">PUGIXML_API</a>
macro, i.e. via <code class="filename">pugiconfig.hpp</code>:
</p>
<pre class="programlisting"><span class="preprocessor">#ifdef</span> <span class="identifier">_DLL</span>
<span class="preprocessor">#define</span> <span class="identifier">PUGIXML_API</span> <span class="identifier">__declspec</span><span class="special">(</span><span class="identifier">dllexport</span><span class="special">)</span>
<span class="preprocessor">#else</span>
<span class="preprocessor">#define</span> <span class="identifier">PUGIXML_API</span> <span class="identifier">__declspec</span><span class="special">(</span><span class="identifier">dllimport</span><span class="special">)</span>
<span class="preprocessor">#endif</span>
</pre>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
If you're using STL-related functions, you should use the shared runtime
library to ensure that a single heap is used for STL allocations in your
application and in pugixml; in MSVC, this means selecting the 'Multithreaded
DLL' or 'Multithreaded Debug DLL' to 'Runtime library' property (/MD
or /MDd linker switch). You should also make sure that your runtime library
choice is consistent between different projects.
</p></td></tr>
</table></div>
</div>
<a name="PUGIXML_HEADER_ONLY"></a><div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.install.building.header"></a><a class="link" href="install.html#manual.install.building.header" title="Using pugixml in header-only mode"> Using pugixml in header-only
mode</a>
</h4></div></div></div>
<p>
It's possible to use pugixml in header-only mode. This means that all source
code for pugixml will be included in every translation unit that includes
<code class="filename">pugixml.hpp</code>. This is how most of Boost and STL libraries work.
</p>
<p>
Note that there are advantages and drawbacks of this approach. Header mode
may improve tree traversal/modification performance (because many simple
functions will be inlined), if your compiler toolchain does not support
link-time optimization, or if you have it turned off (with link-time optimization
the performance should be similar to non-header mode). However, since compiler
now has to compile pugixml source once for each translation unit that includes
it, compilation times may increase noticeably. If you want to use pugixml
in header mode but do not need XPath support, you can consider disabling
it by using <a class="link" href="install.html#PUGIXML_NO_XPATH">PUGIXML_NO_XPATH</a> define
to improve compilation time.
</p>
<p>
Enabling header-only mode is a two-step process:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
You have to define <code class="computeroutput"><span class="identifier">PUGIXML_HEADER_ONLY</span></code>
</li>
<li class="listitem">
You have to include <code class="filename">pugixml.cpp</code> whenever you include pugixml.hpp
</li>
</ol></div>
<p>
Both of these are best done via <code class="filename">pugiconfig.hpp</code> like this:
</p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">PUGIXML_HEADER_ONLY</span>
<span class="preprocessor">#include</span> <span class="string">"pugixml.cpp"</span>
</pre>
<p>
Note that it is safe to compile <code class="filename">pugixml.cpp</code> if <code class="computeroutput"><span class="identifier">PUGIXML_HEADER_ONLY</span></code>
is defined - so if you want to i.e. use header-only mode only in Release
configuration, you can include pugixml.cpp in your project (see <a class="xref" href="install.html#manual.install.building.embed" title="Building pugixml as a part of another static library/executable"> Building pugixml as
a part of another static library/executable</a>),
and conditionally enable header-only mode in <code class="filename">pugiconfig.hpp</code>, i.e.:
</p>
<pre class="programlisting"><span class="preprocessor">#ifndef</span> <span class="identifier">_DEBUG</span>
<span class="preprocessor">#define</span> <span class="identifier">PUGIXML_HEADER_ONLY</span>
<span class="preprocessor">#include</span> <span class="string">"pugixml.cpp"</span>
<span class="preprocessor">#endif</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="manual.install.building.config"></a><a class="link" href="install.html#manual.install.building.config" title="Additional configuration options"> Additional configuration
options</a>
</h4></div></div></div>
<p>
pugixml uses several defines to control the compilation process. There
are two ways to define them: either put the needed definitions to <code class="filename">pugiconfig.hpp</code> (it
has some examples that are commented out) or provide them via compiler
command-line. Consistency is important: the definitions should match in
all source files that include <code class="filename">pugixml.hpp</code> (including pugixml sources) throughout
the application. Adding defines to <code class="filename">pugiconfig.hpp</code> lets you guarantee this,
unless your macro definition is wrapped in preprocessor <code class="computeroutput"><span class="preprocessor">#if</span></code>/<code class="computeroutput"><span class="preprocessor">#ifdef</span></code> directive and this directive
is not consistent. <code class="filename">pugiconfig.hpp</code> will never contain anything but comments,
which means that when upgrading to a new version, you can safely leave
your modified version intact.
</p>
<p>
<a name="PUGIXML_WCHAR_MODE"></a><code class="literal">PUGIXML_WCHAR_MODE</code> define toggles
between UTF-8 style interface (the in-memory text encoding is assumed to
be UTF-8, most functions use <code class="computeroutput"><span class="keyword">char</span></code>
as character type) and UTF-16/32 style interface (the in-memory text encoding
is assumed to be UTF-16/32, depending on <code class="computeroutput"><span class="keyword">wchar_t</span></code>
size, most functions use <code class="computeroutput"><span class="keyword">wchar_t</span></code>
as character type). See <a class="xref" href="dom.html#manual.dom.unicode" title="Unicode interface"> Unicode interface</a> for more details.
</p>
<p>
<a name="PUGIXML_NO_XPATH"></a><code class="literal">PUGIXML_NO_XPATH</code> define disables XPath.
Both XPath interfaces and XPath implementation are excluded from compilation.
This option is provided in case you do not need XPath functionality and
need to save code space.
</p>
<p>
<a name="PUGIXML_NO_STL"></a><code class="literal">PUGIXML_NO_STL</code> define disables use of
STL in pugixml. The functions that operate on STL types are no longer present
(i.e. load/save via iostream) if this macro is defined. This option is
provided in case your target platform does not have a standard-compliant
STL implementation.
</p>
<p>
<a name="PUGIXML_NO_EXCEPTIONS"></a><code class="literal">PUGIXML_NO_EXCEPTIONS</code> define disables
use of exceptions in pugixml. This option is provided in case your target
platform does not have exception handling capabilities.
</p>
<p>
<a name="PUGIXML_API"></a><code class="literal">PUGIXML_API</code>, <a name="PUGIXML_CLASS"></a><code class="literal">PUGIXML_CLASS</code>
and <a name="PUGIXML_FUNCTION"></a><code class="literal">PUGIXML_FUNCTION</code> defines let you
specify custom attributes (i.e. declspec or calling conventions) for pugixml
classes and non-member functions. In absence of <code class="computeroutput"><span class="identifier">PUGIXML_CLASS</span></code>
or <code class="computeroutput"><span class="identifier">PUGIXML_FUNCTION</span></code> definitions,
<code class="computeroutput"><span class="identifier">PUGIXML_API</span></code> definition
is used instead. For example, to specify fixed calling convention, you
can define <code class="computeroutput"><span class="identifier">PUGIXML_FUNCTION</span></code>
to i.e. <code class="computeroutput"><span class="identifier">__fastcall</span></code>. Another
example is DLL import/export attributes in MSVC (see <a class="xref" href="install.html#manual.install.building.shared" title="Building pugixml as a standalone shared library"> Building pugixml as
a standalone shared library</a>).
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
In that example <code class="computeroutput"><span class="identifier">PUGIXML_API</span></code>
is inconsistent between several source files; this is an exception to
the consistency rule.
</p></td></tr>
</table></div>
<p>
<a name="PUGIXML_MEMORY_PAGE_SIZE"></a><code class="literal">PUGIXML_MEMORY_PAGE_SIZE</code>, <a name="PUGIXML_MEMORY_OUTPUT_STACK"></a><code class="literal">PUGIXML_MEMORY_OUTPUT_STACK</code>
and <a name="PUGIXML_MEMORY_XPATH_PAGE_SIZE"></a><code class="literal">PUGIXML_MEMORY_XPATH_PAGE_SIZE</code>
can be used to customize certain important sizes to optimize memory usage
for the application-specific patterns. For details see <a class="xref" href="dom.html#manual.dom.memory.tuning" title="Memory consumption tuning"> Memory consumption tuning</a>.
</p>
<p>
<a name="PUGIXML_HAS_LONG_LONG"></a><code class="literal">PUGIXML_HAS_LONG_LONG</code> define enables
support for <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">long</span></code>
type in pugixml. This define is automatically enabled if your platform
is known to have <code class="computeroutput"><span class="keyword">long</span> <span class="keyword">long</span></code>
support (i.e. has C++-11 support or uses a reasonably modern version of
a known compiler); if pugixml does not recognize that your platform supports
<code class="computeroutput"><span class="keyword">long</span> <span class="keyword">long</span></code>
but in fact it does, you can enable the define manually.
</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.install.portability"></a><a class="link" href="install.html#manual.install.portability" title="Portability"> Portability</a>
</h3></div></div></div>
<p>
pugixml is written in standard-compliant C++ with some compiler-specific
workarounds where appropriate. pugixml is compatible with the C++11 standard,
but does not require C++11 support. Each version is tested with a unit test
suite (with code coverage about 99%) on the following platforms:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Microsoft Windows:
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
Borland C++ Compiler 5.82
</li>
<li class="listitem">
Digital Mars C++ Compiler 8.51
</li>
<li class="listitem">
Intel C++ Compiler 8.0, 9.0 x86/x64, 10.0 x86/x64, 11.0 x86/x64
</li>
<li class="listitem">
Metrowerks CodeWarrior 8.0
</li>
<li class="listitem">
Microsoft Visual C++ 6.0, 7.0 (2002), 7.1 (2003), 8.0 (2005) x86/x64,
9.0 (2008) x86/x64, 10.0 (2010) x86/x64, 11.0 (2011) x86/x64/ARM,
12.0 (2013) x86/x64/ARM and some CLR versions
</li>
<li class="listitem">
MinGW (GCC) 3.4, 4.4, 4.5, 4.6 x64
</li>
</ul></div>
</li>
<li class="listitem">
Linux (GCC 4.4.3 x86/x64, GCC 4.8.1 x64, Clang 3.2 x64)
</li>
<li class="listitem">
FreeBSD (GCC 4.2.1 x86/x64)
</li>
<li class="listitem">
Apple MacOSX (GCC 4.0.1 x86/x64/PowerPC)
</li>
<li class="listitem">
Sun Solaris (sunCC x86/x64)
</li>
<li class="listitem">
Microsoft Xbox 360
</li>
<li class="listitem">
Nintendo Wii (Metrowerks CodeWarrior 4.1)
</li>
<li class="listitem">
Sony Playstation Portable (GCC 3.4.2)
</li>
<li class="listitem">
Sony Playstation 3 (GCC 4.1.1, SNC 310.1)
</li>
<li class="listitem">
Various portable platforms (Android NDK, BlackBerry NDK, Samsung bada,
Windows CE)
</li>
</ul></div>
</div>
<div class="footnotes">
<br><hr style="width:100; text-align:left;margin-left: 0">
<div id="ftn.trademarks" class="footnote"><p><a href="#trademarks" class="para"><sup class="para">[1] </sup></a>All trademarks used are properties of their respective
owners.</p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<b>Installation</b> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="../manual.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="dom.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
</body>
</html>

View file

@ -1,914 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Loading document</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="dom.html" title="Document object model">
<link rel="next" href="access.html" title="Accessing document data">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <b>Loading</b> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="dom.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="access.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.loading"></a><a class="link" href="loading.html" title="Loading document"> Loading document</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="loading.html#manual.loading.file"> Loading document from file</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.memory"> Loading document from memory</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.stream"> Loading document from C++ IOstreams</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.errors"> Handling parsing errors</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.options"> Parsing options</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.encoding"> Encodings</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.w3c"> Conformance to W3C specification</a></span></dt>
</dl></div>
<p>
pugixml provides several functions for loading XML data from various places
- files, C++ iostreams, memory buffers. All functions use an extremely fast
non-validating parser. This parser is not fully W3C conformant - it can load
any valid XML document, but does not perform some well-formedness checks. While
considerable effort is made to reject invalid XML documents, some validation
is not performed for performance reasons. Also some XML transformations (i.e.
EOL handling or attribute value normalization) can impact parsing speed and
thus can be disabled. However for vast majority of XML documents there is no
performance difference between different parsing options. Parsing options also
control whether certain XML nodes are parsed; see <a class="xref" href="loading.html#manual.loading.options" title="Parsing options"> Parsing options</a> for
more information.
</p>
<p>
XML data is always converted to internal character format (see <a class="xref" href="dom.html#manual.dom.unicode" title="Unicode interface"> Unicode interface</a>)
before parsing. pugixml supports all popular Unicode encodings (UTF-8, UTF-16
(big and little endian), UTF-32 (big and little endian); UCS-2 is naturally
supported since it's a strict subset of UTF-16) and handles all encoding conversions
automatically. Unless explicit encoding is specified, loading functions perform
automatic encoding detection based on first few characters of XML data, so
in almost all cases you do not have to specify document encoding. Encoding
conversion is described in more detail in <a class="xref" href="loading.html#manual.loading.encoding" title="Encodings"> Encodings</a>.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.loading.file"></a><a class="link" href="loading.html#manual.loading.file" title="Loading document from file"> Loading document from file</a>
</h3></div></div></div>
<a name="xml_document::load_file"></a><a name="xml_document::load_file_wide"></a><p>
The most common source of XML data is files; pugixml provides dedicated functions
for loading an XML document from file:
</p>
<pre class="programlisting"><span class="identifier">xml_parse_result</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load_file</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">path</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">);</span>
<span class="identifier">xml_parse_result</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load_file</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">path</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">);</span>
</pre>
<p>
These functions accept the file path as its first argument, and also two
optional arguments, which specify parsing options (see <a class="xref" href="loading.html#manual.loading.options" title="Parsing options"> Parsing options</a>)
and input data encoding (see <a class="xref" href="loading.html#manual.loading.encoding" title="Encodings"> Encodings</a>). The path has the target
operating system format, so it can be a relative or absolute one, it should
have the delimiters of the target system, it should have the exact case if
the target file system is case-sensitive, etc.
</p>
<p>
File path is passed to the system file opening function as is in case of
the first function (which accepts <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">char</span><span class="special">*</span> <span class="identifier">path</span></code>); the second function either uses
a special file opening function if it is provided by the runtime library
or converts the path to UTF-8 and uses the system file opening function.
</p>
<p>
<code class="computeroutput"><span class="identifier">load_file</span></code> destroys the existing
document tree and then tries to load the new tree from the specified file.
The result of the operation is returned in an <a class="link" href="loading.html#xml_parse_result">xml_parse_result</a>
object; this object contains the operation status and the related information
(i.e. last successfully parsed position in the input file, if parsing fails).
See <a class="xref" href="loading.html#manual.loading.errors" title="Handling parsing errors"> Handling parsing errors</a> for error handling details.
</p>
<p>
This is an example of loading XML document from file (<a href="../samples/load_file.cpp" target="_top">samples/load_file.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_file</span><span class="special">(</span><span class="string">"tree.xml"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Load result: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">description</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">", mesh name: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"mesh"</span><span class="special">).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"name"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.loading.memory"></a><a class="link" href="loading.html#manual.loading.memory" title="Loading document from memory"> Loading document from memory</a>
</h3></div></div></div>
<a name="xml_document::load_buffer"></a><a name="xml_document::load_buffer_inplace"></a><a name="xml_document::load_buffer_inplace_own"></a><p>
Sometimes XML data should be loaded from some other source than a file, i.e.
HTTP URL; also you may want to load XML data from file using non-standard
functions, i.e. to use your virtual file system facilities or to load XML
from gzip-compressed files. All these scenarios require loading document
from memory. First you should prepare a contiguous memory block with all
XML data; then you have to invoke one of buffer loading functions. These
functions will handle the necessary encoding conversions, if any, and then
will parse the data into the corresponding XML tree. There are several buffer
loading functions, which differ in the behavior and thus in performance/memory
usage:
</p>
<pre class="programlisting"><span class="identifier">xml_parse_result</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load_buffer</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">contents</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">);</span>
<span class="identifier">xml_parse_result</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load_buffer_inplace</span><span class="special">(</span><span class="keyword">void</span><span class="special">*</span> <span class="identifier">contents</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">);</span>
<span class="identifier">xml_parse_result</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load_buffer_inplace_own</span><span class="special">(</span><span class="keyword">void</span><span class="special">*</span> <span class="identifier">contents</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">);</span>
</pre>
<p>
All functions accept the buffer which is represented by a pointer to XML
data, <code class="computeroutput"><span class="identifier">contents</span></code>, and data
size in bytes. Also there are two optional arguments, which specify parsing
options (see <a class="xref" href="loading.html#manual.loading.options" title="Parsing options"> Parsing options</a>) and input data encoding (see <a class="xref" href="loading.html#manual.loading.encoding" title="Encodings"> Encodings</a>).
The buffer does not have to be zero-terminated.
</p>
<p>
<code class="computeroutput"><span class="identifier">load_buffer</span></code> function works
with immutable buffer - it does not ever modify the buffer. Because of this
restriction it has to create a private buffer and copy XML data to it before
parsing (applying encoding conversions if necessary). This copy operation
carries a performance penalty, so inplace functions are provided - <code class="computeroutput"><span class="identifier">load_buffer_inplace</span></code> and <code class="computeroutput"><span class="identifier">load_buffer_inplace_own</span></code>
store the document data in the buffer, modifying it in the process. In order
for the document to stay valid, you have to make sure that the buffer's lifetime
exceeds that of the tree if you're using inplace functions. In addition to
that, <code class="computeroutput"><span class="identifier">load_buffer_inplace</span></code>
does not assume ownership of the buffer, so you'll have to destroy it yourself;
<code class="computeroutput"><span class="identifier">load_buffer_inplace_own</span></code> assumes
ownership of the buffer and destroys it once it is not needed. This means
that if you're using <code class="computeroutput"><span class="identifier">load_buffer_inplace_own</span></code>,
you have to allocate memory with pugixml allocation function (you can get
it via <a class="link" href="dom.html#get_memory_allocation_function">get_memory_allocation_function</a>).
</p>
<p>
The best way from the performance/memory point of view is to load document
using <code class="computeroutput"><span class="identifier">load_buffer_inplace_own</span></code>;
this function has maximum control of the buffer with XML data so it is able
to avoid redundant copies and reduce peak memory usage while parsing. This
is the recommended function if you have to load the document from memory
and performance is critical.
</p>
<a name="xml_document::load_string"></a><p>
There is also a simple helper function for cases when you want to load the
XML document from null-terminated character string:
</p>
<pre class="programlisting"><span class="identifier">xml_parse_result</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load_string</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">contents</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">);</span>
</pre>
<p>
It is equivalent to calling <code class="computeroutput"><span class="identifier">load_buffer</span></code>
with <code class="computeroutput"><span class="identifier">size</span></code> being either <code class="computeroutput"><span class="identifier">strlen</span><span class="special">(</span><span class="identifier">contents</span><span class="special">)</span></code>
or <code class="computeroutput"><span class="identifier">wcslen</span><span class="special">(</span><span class="identifier">contents</span><span class="special">)</span> <span class="special">*</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="keyword">wchar_t</span><span class="special">)</span></code>,
depending on the character type. This function assumes native encoding for
input data, so it does not do any encoding conversion. In general, this function
is fine for loading small documents from string literals, but has more overhead
and less functionality than the buffer loading functions.
</p>
<p>
This is an example of loading XML document from memory using different functions
(<a href="../samples/load_memory.cpp" target="_top">samples/load_memory.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">char</span> <span class="identifier">source</span><span class="special">[]</span> <span class="special">=</span> <span class="string">"&lt;mesh name='sphere'&gt;&lt;bounds&gt;0 0 1 1&lt;/bounds&gt;&lt;/mesh&gt;"</span><span class="special">;</span>
<span class="identifier">size_t</span> <span class="identifier">size</span> <span class="special">=</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">source</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// You can use load_buffer to load document from immutable memory block:
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_buffer</span><span class="special">(</span><span class="identifier">source</span><span class="special">,</span> <span class="identifier">size</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// You can use load_buffer_inplace to load document from mutable memory block; the block's lifetime must exceed that of document
</span><span class="keyword">char</span><span class="special">*</span> <span class="identifier">buffer</span> <span class="special">=</span> <span class="keyword">new</span> <span class="keyword">char</span><span class="special">[</span><span class="identifier">size</span><span class="special">];</span>
<span class="identifier">memcpy</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">source</span><span class="special">,</span> <span class="identifier">size</span><span class="special">);</span>
<span class="comment">// The block can be allocated by any method; the block is modified during parsing
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_buffer_inplace</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">size</span><span class="special">);</span>
<span class="comment">// You have to destroy the block yourself after the document is no longer used
</span><span class="keyword">delete</span><span class="special">[]</span> <span class="identifier">buffer</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// You can use load_buffer_inplace_own to load document from mutable memory block and to pass the ownership of this block
</span><span class="comment">// The block has to be allocated via pugixml allocation function - using i.e. operator new here is incorrect
</span><span class="keyword">char</span><span class="special">*</span> <span class="identifier">buffer</span> <span class="special">=</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">get_memory_allocation_function</span><span class="special">()(</span><span class="identifier">size</span><span class="special">));</span>
<span class="identifier">memcpy</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">source</span><span class="special">,</span> <span class="identifier">size</span><span class="special">);</span>
<span class="comment">// The block will be deleted by the document
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_buffer_inplace_own</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">size</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// You can use load to load document from null-terminated strings, for example literals:
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="string">"&lt;mesh name='sphere'&gt;&lt;bounds&gt;0 0 1 1&lt;/bounds&gt;&lt;/mesh&gt;"</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.loading.stream"></a><a class="link" href="loading.html#manual.loading.stream" title="Loading document from C++ IOstreams"> Loading document from C++ IOstreams</a>
</h3></div></div></div>
<a name="xml_document::load_stream"></a><p>
To enhance interoperability, pugixml provides functions for loading document
from any object which implements C++ <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code>
interface. This allows you to load documents from any standard C++ stream
(i.e. file stream) or any third-party compliant implementation (i.e. Boost
Iostreams). There are two functions, one works with narrow character streams,
another handles wide character ones:
</p>
<pre class="programlisting"><span class="identifier">xml_parse_result</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&amp;</span> <span class="identifier">stream</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">);</span>
<span class="identifier">xml_parse_result</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">wistream</span><span class="special">&amp;</span> <span class="identifier">stream</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">);</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">load</span></code> with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code>
argument loads the document from stream from the current read position to
the end, treating the stream contents as a byte stream of the specified encoding
(with encoding autodetection as necessary). Thus calling <code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load</span></code>
on an opened <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ifstream</span></code> object is equivalent to calling
<code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load_file</span></code>.
</p>
<p>
<code class="computeroutput"><span class="identifier">load</span></code> with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstream</span></code>
argument treats the stream contents as a wide character stream (encoding
is always <a class="link" href="loading.html#encoding_wchar">encoding_wchar</a>). Because
of this, using <code class="computeroutput"><span class="identifier">load</span></code> with
wide character streams requires careful (usually platform-specific) stream
setup (i.e. using the <code class="computeroutput"><span class="identifier">imbue</span></code>
function). Generally use of wide streams is discouraged, however it provides
you the ability to load documents from non-Unicode encodings, i.e. you can
load Shift-JIS encoded data if you set the correct locale.
</p>
<p>
This is a simple example of loading XML document from file using streams
(<a href="../samples/load_stream.cpp" target="_top">samples/load_stream.cpp</a>); read
the sample code for more complex examples involving wide streams and locales:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ifstream</span> <span class="identifier">stream</span><span class="special">(</span><span class="string">"weekly-utf-8.xml"</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">stream</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.loading.errors"></a><a class="link" href="loading.html#manual.loading.errors" title="Handling parsing errors"> Handling parsing errors</a>
</h3></div></div></div>
<a name="xml_parse_result"></a><p>
All document loading functions return the parsing result via <code class="computeroutput"><span class="identifier">xml_parse_result</span></code> object. It contains parsing
status, the offset of last successfully parsed character from the beginning
of the source stream, and the encoding of the source stream:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">xml_parse_result</span>
<span class="special">{</span>
<span class="identifier">xml_parse_status</span> <span class="identifier">status</span><span class="special">;</span>
<span class="identifier">ptrdiff_t</span> <span class="identifier">offset</span><span class="special">;</span>
<span class="identifier">xml_encoding</span> <span class="identifier">encoding</span><span class="special">;</span>
<span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">description</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<a name="xml_parse_status"></a><a name="xml_parse_result::status"></a><p>
Parsing status is represented as the <code class="computeroutput"><span class="identifier">xml_parse_status</span></code>
enumeration and can be one of the following:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a name="status_ok"></a><code class="literal">status_ok</code> means that no error was encountered
during parsing; the source stream represents the valid XML document which
was fully parsed and converted to a tree. <br><br>
</li>
<li class="listitem">
<a name="status_file_not_found"></a><code class="literal">status_file_not_found</code> is only
returned by <code class="computeroutput"><span class="identifier">load_file</span></code>
function and means that file could not be opened.
</li>
<li class="listitem">
<a name="status_io_error"></a><code class="literal">status_io_error</code> is returned by <code class="computeroutput"><span class="identifier">load_file</span></code> function and by <code class="computeroutput"><span class="identifier">load</span></code> functions with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code>/<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstream</span></code> arguments; it means that some
I/O error has occurred during reading the file/stream.
</li>
<li class="listitem">
<a name="status_out_of_memory"></a><code class="literal">status_out_of_memory</code> means that
there was not enough memory during some allocation; any allocation failure
during parsing results in this error.
</li>
<li class="listitem">
<a name="status_internal_error"></a><code class="literal">status_internal_error</code> means that
something went horribly wrong; currently this error does not occur <br><br>
</li>
<li class="listitem">
<a name="status_unrecognized_tag"></a><code class="literal">status_unrecognized_tag</code> means
that parsing stopped due to a tag with either an empty name or a name
which starts with incorrect character, such as <code class="literal">#</code>.
</li>
<li class="listitem">
<a name="status_bad_pi"></a><code class="literal">status_bad_pi</code> means that parsing stopped
due to incorrect document declaration/processing instruction
</li>
<li class="listitem">
<a name="status_bad_comment"></a><code class="literal">status_bad_comment</code>, <a name="status_bad_cdata"></a><code class="literal">status_bad_cdata</code>,
<a name="status_bad_doctype"></a><code class="literal">status_bad_doctype</code> and <a name="status_bad_pcdata"></a><code class="literal">status_bad_pcdata</code>
mean that parsing stopped due to the invalid construct of the respective
type
</li>
<li class="listitem">
<a name="status_bad_start_element"></a><code class="literal">status_bad_start_element</code> means
that parsing stopped because starting tag either had no closing <code class="computeroutput"><span class="special">&gt;</span></code> symbol or contained some incorrect
symbol
</li>
<li class="listitem">
<a name="status_bad_attribute"></a><code class="literal">status_bad_attribute</code> means that
parsing stopped because there was an incorrect attribute, such as an
attribute without value or with value that is not quoted (note that
<code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span>
<span class="identifier">attr</span><span class="special">=</span><span class="number">1</span><span class="special">&gt;</span></code> is
incorrect in XML)
</li>
<li class="listitem">
<a name="status_bad_end_element"></a><code class="literal">status_bad_end_element</code> means
that parsing stopped because ending tag had incorrect syntax (i.e. extra
non-whitespace symbols between tag name and <code class="computeroutput"><span class="special">&gt;</span></code>)
</li>
<li class="listitem">
<a name="status_end_element_mismatch"></a><code class="literal">status_end_element_mismatch</code>
means that parsing stopped because the closing tag did not match the
opening one (i.e. <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;&lt;/</span><span class="identifier">nedo</span><span class="special">&gt;</span></code>) or because some tag was not closed
at all
</li>
<li class="listitem">
<a name="status_no_document_element"></a><code class="literal">status_no_document_element</code>
means that no element nodes were discovered during parsing; this usually
indicates an empty or invalid document
</li>
</ul></div>
<a name="xml_parse_result::description"></a><p>
<code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code>
member function can be used to convert parsing status to a string; the returned
message is always in English, so you'll have to write your own function if
you need a localized string. However please note that the exact messages
returned by <code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code>
function may change from version to version, so any complex status handling
should be based on <code class="computeroutput"><span class="identifier">status</span></code>
value. Note that <code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code> returns a <code class="computeroutput"><span class="keyword">char</span></code>
string even in <code class="computeroutput"><span class="identifier">PUGIXML_WCHAR_MODE</span></code>;
you'll have to call <a class="link" href="dom.html#as_wide">as_wide</a> to get the <code class="computeroutput"><span class="keyword">wchar_t</span></code> string.
</p>
<p>
If parsing failed because the source data was not a valid XML, the resulting
tree is not destroyed - despite the fact that load function returns error,
you can use the part of the tree that was successfully parsed. Obviously,
the last element may have an unexpected name/value; for example, if the attribute
value does not end with the necessary quotation mark, like in <code class="literal">&lt;node
attr="value&gt;some data&lt;/node&gt;</code> example, the value of
attribute <code class="computeroutput"><span class="identifier">attr</span></code> will contain
the string <code class="computeroutput"><span class="identifier">value</span><span class="special">&gt;</span><span class="identifier">some</span> <span class="identifier">data</span><span class="special">&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span></code>.
</p>
<a name="xml_parse_result::offset"></a><p>
In addition to the status code, parsing result has an <code class="computeroutput"><span class="identifier">offset</span></code>
member, which contains the offset of last successfully parsed character if
parsing failed because of an error in source data; otherwise <code class="computeroutput"><span class="identifier">offset</span></code> is 0. For parsing efficiency reasons,
pugixml does not track the current line during parsing; this offset is in
units of <a class="link" href="dom.html#char_t">pugi::char_t</a> (bytes for character
mode, wide characters for wide character mode). Many text editors support
'Go To Position' feature - you can use it to locate the exact error position.
Alternatively, if you're loading the document from memory, you can display
the error chunk along with the error description (see the example code below).
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
Offset is calculated in the XML buffer in native encoding; if encoding
conversion is performed during parsing, offset can not be used to reliably
track the error position.
</p></td></tr>
</table></div>
<a name="xml_parse_result::encoding"></a><p>
Parsing result also has an <code class="computeroutput"><span class="identifier">encoding</span></code>
member, which can be used to check that the source data encoding was correctly
guessed. It is equal to the exact encoding used during parsing (i.e. with
the exact endianness); see <a class="xref" href="loading.html#manual.loading.encoding" title="Encodings"> Encodings</a> for more information.
</p>
<a name="xml_parse_result::bool"></a><p>
Parsing result object can be implicitly converted to <code class="computeroutput"><span class="keyword">bool</span></code>;
if you do not want to handle parsing errors thoroughly, you can just check
the return value of load functions as if it was a <code class="computeroutput"><span class="keyword">bool</span></code>:
<code class="computeroutput"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_file</span><span class="special">(</span><span class="string">"file.xml"</span><span class="special">))</span> <span class="special">{</span> <span class="special">...</span>
<span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>.
</p>
<p>
This is an example of handling loading errors (<a href="../samples/load_error_handling.cpp" target="_top">samples/load_error_handling.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="identifier">source</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"XML ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">source</span> <span class="special">&lt;&lt;</span> <span class="string">"] parsed without errors, attr value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"node"</span><span class="special">).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"attr"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n\n"</span><span class="special">;</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"XML ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">source</span> <span class="special">&lt;&lt;</span> <span class="string">"] parsed with errors, attr value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"node"</span><span class="special">).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"attr"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n"</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Error description: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">description</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Error offset: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">offset</span> <span class="special">&lt;&lt;</span> <span class="string">" (error at [..."</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">source</span> <span class="special">+</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">offset</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.loading.options"></a><a class="link" href="loading.html#manual.loading.options" title="Parsing options"> Parsing options</a>
</h3></div></div></div>
<p>
All document loading functions accept the optional parameter <code class="computeroutput"><span class="identifier">options</span></code>. This is a bitmask that customizes
the parsing process: you can select the node types that are parsed and various
transformations that are performed with the XML text. Disabling certain transformations
can improve parsing performance for some documents; however, the code for
all transformations is very well optimized, and thus the majority of documents
won't get any performance benefit. As a rule of thumb, only modify parsing
flags if you want to get some nodes in the document that are excluded by
default (i.e. declaration or comment nodes).
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
You should use the usual bitwise arithmetics to manipulate the bitmask:
to enable a flag, use <code class="computeroutput"><span class="identifier">mask</span> <span class="special">|</span> <span class="identifier">flag</span></code>;
to disable a flag, use <code class="computeroutput"><span class="identifier">mask</span> <span class="special">&amp;</span> <span class="special">~</span><span class="identifier">flag</span></code>.
</p></td></tr>
</table></div>
<p>
These flags control the resulting tree contents:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a name="parse_declaration"></a><code class="literal">parse_declaration</code> determines if XML
document declaration (node with type <a class="link" href="dom.html#node_declaration">node_declaration</a>)
is to be put in DOM tree. If this flag is off, it is not put in the tree,
but is still parsed and checked for correctness. This flag is <span class="bold"><strong>off</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="parse_doctype"></a><code class="literal">parse_doctype</code> determines if XML document
type declaration (node with type <a class="link" href="dom.html#node_doctype">node_doctype</a>)
is to be put in DOM tree. If this flag is off, it is not put in the tree,
but is still parsed and checked for correctness. This flag is <span class="bold"><strong>off</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="parse_pi"></a><code class="literal">parse_pi</code> determines if processing instructions
(nodes with type <a class="link" href="dom.html#node_pi">node_pi</a>) are to be put
in DOM tree. If this flag is off, they are not put in the tree, but are
still parsed and checked for correctness. Note that <code class="computeroutput"><span class="special">&lt;?</span><span class="identifier">xml</span> <span class="special">...?&gt;</span></code>
(document declaration) is not considered to be a PI. This flag is <span class="bold"><strong>off</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="parse_comments"></a><code class="literal">parse_comments</code> determines if comments
(nodes with type <a class="link" href="dom.html#node_comment">node_comment</a>) are
to be put in DOM tree. If this flag is off, they are not put in the tree,
but are still parsed and checked for correctness. This flag is <span class="bold"><strong>off</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="parse_cdata"></a><code class="literal">parse_cdata</code> determines if CDATA sections
(nodes with type <a class="link" href="dom.html#node_cdata">node_cdata</a>) are to
be put in DOM tree. If this flag is off, they are not put in the tree,
but are still parsed and checked for correctness. This flag is <span class="bold"><strong>on</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="parse_trim_pcdata"></a><code class="literal">parse_trim_pcdata</code> determines if leading
and trailing whitespace characters are to be removed from PCDATA nodes.
While for some applications leading/trailing whitespace is significant,
often the application only cares about the non-whitespace contents so
it's easier to trim whitespace from text during parsing. This flag is
<span class="bold"><strong>off</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="parse_ws_pcdata"></a><code class="literal">parse_ws_pcdata</code> determines if PCDATA
nodes (nodes with type <a class="link" href="dom.html#node_pcdata">node_pcdata</a>)
that consist only of whitespace characters are to be put in DOM tree.
Often whitespace-only data is not significant for the application, and
the cost of allocating and storing such nodes (both memory and speed-wise)
can be significant. For example, after parsing XML string <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;</span> <span class="special">&lt;</span><span class="identifier">a</span><span class="special">/&gt;</span> <span class="special">&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span></code>, <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;</span></code>
element will have three children when <code class="computeroutput"><span class="identifier">parse_ws_pcdata</span></code>
is set (child with type <a class="link" href="dom.html#node_pcdata">node_pcdata</a>
and value <code class="computeroutput"><span class="string">" "</span></code>,
child with type <a class="link" href="dom.html#node_element">node_element</a> and
name <code class="computeroutput"><span class="string">"a"</span></code>, and another
child with type <a class="link" href="dom.html#node_pcdata">node_pcdata</a> and value
<code class="computeroutput"><span class="string">" "</span></code>), and only
one child when <code class="computeroutput"><span class="identifier">parse_ws_pcdata</span></code>
is not set. This flag is <span class="bold"><strong>off</strong></span> by default.
<br><br>
</li>
<li class="listitem">
<a name="parse_ws_pcdata_single"></a><code class="literal">parse_ws_pcdata_single</code> determines
if whitespace-only PCDATA nodes that have no sibling nodes are to be
put in DOM tree. In some cases application needs to parse the whitespace-only
contents of nodes, i.e. <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;</span>
<span class="special">&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span></code>, but is not interested in whitespace
markup elsewhere. It is possible to use <a class="link" href="loading.html#parse_ws_pcdata">parse_ws_pcdata</a>
flag in this case, but it results in excessive allocations and complicates
document processing in some cases; this flag is intended to avoid that.
As an example, after parsing XML string <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;</span>
<span class="special">&lt;</span><span class="identifier">a</span><span class="special">&gt;</span> <span class="special">&lt;/</span><span class="identifier">a</span><span class="special">&gt;</span> <span class="special">&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span></code> with <code class="computeroutput"><span class="identifier">parse_ws_pcdata_single</span></code>
flag set, <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;</span></code> element will have one child <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">a</span><span class="special">&gt;</span></code>, and <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">a</span><span class="special">&gt;</span></code>
element will have one child with type <a class="link" href="dom.html#node_pcdata">node_pcdata</a>
and value <code class="computeroutput"><span class="string">" "</span></code>.
This flag has no effect if <a class="link" href="loading.html#parse_ws_pcdata">parse_ws_pcdata</a>
is enabled. This flag is <span class="bold"><strong>off</strong></span> by default.
<br><br>
</li>
<li class="listitem">
<a name="parse_fragment"></a><code class="literal">parse_fragment</code> determines if document
should be treated as a fragment of a valid XML. Parsing document as a
fragment leads to top-level PCDATA content (i.e. text that is not located
inside a node) to be added to a tree, and additionally treats documents
without element nodes as valid. This flag is <span class="bold"><strong>off</strong></span>
by default.
</li>
</ul></div>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
Using in-place parsing (<a class="link" href="loading.html#xml_document::load_buffer_inplace">load_buffer_inplace</a>)
with <code class="computeroutput"><span class="identifier">parse_fragment</span></code> flag
may result in the loss of the last character of the buffer if it is a part
of PCDATA. Since PCDATA values are null-terminated strings, the only way
to resolve this is to provide a null-terminated buffer as an input to
<code class="computeroutput"><span class="identifier">load_buffer_inplace</span></code> - i.e.
<code class="computeroutput"><span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_buffer_inplace</span><span class="special">(</span><span class="string">"test\0"</span><span class="special">,</span>
<span class="number">5</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_default</span> <span class="special">|</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_fragment</span><span class="special">)</span></code>.
</p></td></tr>
</table></div>
<p>
These flags control the transformation of tree element contents:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a name="parse_escapes"></a><code class="literal">parse_escapes</code> determines if character
and entity references are to be expanded during the parsing process.
Character references have the form <code class="literal">&amp;#...;</code> or
<code class="literal">&amp;#x...;</code> (<code class="literal">...</code> is Unicode numeric
representation of character in either decimal (<code class="literal">&amp;#...;</code>)
or hexadecimal (<code class="literal">&amp;#x...;</code>) form), entity references
are <code class="literal">&amp;lt;</code>, <code class="literal">&amp;gt;</code>, <code class="literal">&amp;amp;</code>,
<code class="literal">&amp;apos;</code> and <code class="literal">&amp;quot;</code> (note
that as pugixml does not handle DTD, the only allowed entities are predefined
ones). If character/entity reference can not be expanded, it is left
as is, so you can do additional processing later. Reference expansion
is performed on attribute values and PCDATA content. This flag is <span class="bold"><strong>on</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="parse_eol"></a><code class="literal">parse_eol</code> determines if EOL handling (that
is, replacing sequences <code class="computeroutput"><span class="number">0x0d</span> <span class="number">0x0a</span></code> by a single <code class="computeroutput"><span class="number">0x0a</span></code>
character, and replacing all standalone <code class="computeroutput"><span class="number">0x0d</span></code>
characters by <code class="computeroutput"><span class="number">0x0a</span></code>) is to
be performed on input data (that is, comments contents, PCDATA/CDATA
contents and attribute values). This flag is <span class="bold"><strong>on</strong></span>
by default. <br><br>
</li>
<li class="listitem">
<a name="parse_wconv_attribute"></a><code class="literal">parse_wconv_attribute</code> determines
if attribute value normalization should be performed for all attributes.
This means, that whitespace characters (new line, tab and space) are
replaced with space (<code class="computeroutput"><span class="char">' '</span></code>).
New line characters are always treated as if <a class="link" href="loading.html#parse_eol">parse_eol</a>
is set, i.e. <code class="computeroutput"><span class="special">\</span><span class="identifier">r</span><span class="special">\</span><span class="identifier">n</span></code>
is converted to a single space. This flag is <span class="bold"><strong>on</strong></span>
by default. <br><br>
</li>
<li class="listitem">
<a name="parse_wnorm_attribute"></a><code class="literal">parse_wnorm_attribute</code> determines
if extended attribute value normalization should be performed for all
attributes. This means, that after attribute values are normalized as
if <a class="link" href="loading.html#parse_wconv_attribute">parse_wconv_attribute</a>
was set, leading and trailing space characters are removed, and all sequences
of space characters are replaced by a single space character. <a class="link" href="loading.html#parse_wconv_attribute">parse_wconv_attribute</a>
has no effect if this flag is on. This flag is <span class="bold"><strong>off</strong></span>
by default.
</li>
</ul></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><span class="identifier">parse_wconv_attribute</span></code> option
performs transformations that are required by W3C specification for attributes
that are declared as <code class="literal">CDATA</code>; <a class="link" href="loading.html#parse_wnorm_attribute">parse_wnorm_attribute</a>
performs transformations required for <code class="literal">NMTOKENS</code> attributes.
In the absence of document type declaration all attributes should behave
as if they are declared as <code class="literal">CDATA</code>, thus <a class="link" href="loading.html#parse_wconv_attribute">parse_wconv_attribute</a>
is the default option.
</p></td></tr>
</table></div>
<p>
Additionally there are three predefined option masks:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a name="parse_minimal"></a><code class="literal">parse_minimal</code> has all options turned
off. This option mask means that pugixml does not add declaration nodes,
document type declaration nodes, PI nodes, CDATA sections and comments
to the resulting tree and does not perform any conversion for input data,
so theoretically it is the fastest mode. However, as mentioned above,
in practice <a class="link" href="loading.html#parse_default">parse_default</a> is usually
equally fast. <br><br>
</li>
<li class="listitem">
<a name="parse_default"></a><code class="literal">parse_default</code> is the default set of flags,
i.e. it has all options set to their default values. It includes parsing
CDATA sections (comments/PIs are not parsed), performing character and
entity reference expansion, replacing whitespace characters with spaces
in attribute values and performing EOL handling. Note, that PCDATA sections
consisting only of whitespace characters are not parsed (by default)
for performance reasons. <br><br>
</li>
<li class="listitem">
<a name="parse_full"></a><code class="literal">parse_full</code> is the set of flags which adds
nodes of all types to the resulting tree and performs default conversions
for input data. It includes parsing CDATA sections, comments, PI nodes,
document declaration node and document type declaration node, performing
character and entity reference expansion, replacing whitespace characters
with spaces in attribute values and performing EOL handling. Note, that
PCDATA sections consisting only of whitespace characters are not parsed
in this mode.
</li>
</ul></div>
<p>
This is an example of using different parsing options (<a href="../samples/load_options.cpp" target="_top">samples/load_options.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">source</span> <span class="special">=</span> <span class="string">"&lt;!--comment--&gt;&lt;node&gt;&amp;lt;&lt;/node&gt;"</span><span class="special">;</span>
<span class="comment">// Parsing with default options; note that comment node is not added to the tree, and entity reference &amp;lt; is expanded
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="identifier">source</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"First node value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">().</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"], node child value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child_value</span><span class="special">(</span><span class="string">"node"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n"</span><span class="special">;</span>
<span class="comment">// Parsing with additional parse_comments option; comment node is now added to the tree
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="identifier">source</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_default</span> <span class="special">|</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_comments</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"First node value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">().</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"], node child value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child_value</span><span class="special">(</span><span class="string">"node"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n"</span><span class="special">;</span>
<span class="comment">// Parsing with additional parse_comments option and without the (default) parse_escapes option; &amp;lt; is not expanded
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="identifier">source</span><span class="special">,</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_default</span> <span class="special">|</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_comments</span><span class="special">)</span> <span class="special">&amp;</span> <span class="special">~</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_escapes</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"First node value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">().</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"], node child value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child_value</span><span class="special">(</span><span class="string">"node"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n"</span><span class="special">;</span>
<span class="comment">// Parsing with minimal option mask; comment node is not added to the tree, and &amp;lt; is not expanded
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="identifier">source</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_minimal</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"First node value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">().</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"], node child value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child_value</span><span class="special">(</span><span class="string">"node"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n"</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.loading.encoding"></a><a class="link" href="loading.html#manual.loading.encoding" title="Encodings"> Encodings</a>
</h3></div></div></div>
<a name="xml_encoding"></a><p>
pugixml supports all popular Unicode encodings (UTF-8, UTF-16 (big and little
endian), UTF-32 (big and little endian); UCS-2 is naturally supported since
it's a strict subset of UTF-16) and handles all encoding conversions. Most
loading functions accept the optional parameter <code class="computeroutput"><span class="identifier">encoding</span></code>.
This is a value of enumeration type <code class="computeroutput"><span class="identifier">xml_encoding</span></code>,
that can have the following values:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a name="encoding_auto"></a><code class="literal">encoding_auto</code> means that pugixml will
try to guess the encoding based on source XML data. The algorithm is
a modified version of the one presented in Appendix F.1 of XML recommendation;
it tries to match the first few bytes of input data with the following
patterns in strict order: <br><br>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
If first four bytes match UTF-32 BOM (Byte Order Mark), encoding
is assumed to be UTF-32 with the endianness equal to that of BOM;
</li>
<li class="listitem">
If first two bytes match UTF-16 BOM, encoding is assumed to be
UTF-16 with the endianness equal to that of BOM;
</li>
<li class="listitem">
If first three bytes match UTF-8 BOM, encoding is assumed to be
UTF-8;
</li>
<li class="listitem">
If first four bytes match UTF-32 representation of <code class="literal">&lt;</code>,
encoding is assumed to be UTF-32 with the corresponding endianness;
</li>
<li class="listitem">
If first four bytes match UTF-16 representation of <code class="literal">&lt;?</code>,
encoding is assumed to be UTF-16 with the corresponding endianness;
</li>
<li class="listitem">
If first two bytes match UTF-16 representation of <code class="literal">&lt;</code>,
encoding is assumed to be UTF-16 with the corresponding endianness
(this guess may yield incorrect result, but it's better than UTF-8);
</li>
<li class="listitem">
Otherwise encoding is assumed to be UTF-8. <br><br>
</li>
</ul></div>
</li>
<li class="listitem">
<a name="encoding_utf8"></a><code class="literal">encoding_utf8</code> corresponds to UTF-8 encoding
as defined in the Unicode standard; UTF-8 sequences with length equal
to 5 or 6 are not standard and are rejected.
</li>
<li class="listitem">
<a name="encoding_utf16_le"></a><code class="literal">encoding_utf16_le</code> corresponds to
little-endian UTF-16 encoding as defined in the Unicode standard; surrogate
pairs are supported.
</li>
<li class="listitem">
<a name="encoding_utf16_be"></a><code class="literal">encoding_utf16_be</code> corresponds to
big-endian UTF-16 encoding as defined in the Unicode standard; surrogate
pairs are supported.
</li>
<li class="listitem">
<a name="encoding_utf16"></a><code class="literal">encoding_utf16</code> corresponds to UTF-16
encoding as defined in the Unicode standard; the endianness is assumed
to be that of the target platform.
</li>
<li class="listitem">
<a name="encoding_utf32_le"></a><code class="literal">encoding_utf32_le</code> corresponds to
little-endian UTF-32 encoding as defined in the Unicode standard.
</li>
<li class="listitem">
<a name="encoding_utf32_be"></a><code class="literal">encoding_utf32_be</code> corresponds to
big-endian UTF-32 encoding as defined in the Unicode standard.
</li>
<li class="listitem">
<a name="encoding_utf32"></a><code class="literal">encoding_utf32</code> corresponds to UTF-32
encoding as defined in the Unicode standard; the endianness is assumed
to be that of the target platform.
</li>
<li class="listitem">
<a name="encoding_wchar"></a><code class="literal">encoding_wchar</code> corresponds to the encoding
of <code class="computeroutput"><span class="keyword">wchar_t</span></code> type; it has
the same meaning as either <code class="computeroutput"><span class="identifier">encoding_utf16</span></code>
or <code class="computeroutput"><span class="identifier">encoding_utf32</span></code>, depending
on <code class="computeroutput"><span class="keyword">wchar_t</span></code> size.
</li>
<li class="listitem">
<a name="encoding_latin1"></a><code class="literal">encoding_latin1</code> corresponds to ISO-8859-1
encoding (also known as Latin-1).
</li>
</ul></div>
<p>
The algorithm used for <code class="computeroutput"><span class="identifier">encoding_auto</span></code>
correctly detects any supported Unicode encoding for all well-formed XML
documents (since they start with document declaration) and for all other
XML documents that start with <code class="literal">&lt;</code>; if your XML document
does not start with <code class="literal">&lt;</code> and has encoding that is different
from UTF-8, use the specific encoding.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The current behavior for Unicode conversion is to skip all invalid UTF
sequences during conversion. This behavior should not be relied upon; moreover,
in case no encoding conversion is performed, the invalid sequences are
not removed, so you'll get them as is in node/attribute contents.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.loading.w3c"></a><a class="link" href="loading.html#manual.loading.w3c" title="Conformance to W3C specification"> Conformance to W3C specification</a>
</h3></div></div></div>
<p>
pugixml is not fully W3C conformant - it can load any valid XML document,
but does not perform some well-formedness checks. While considerable effort
is made to reject invalid XML documents, some validation is not performed
because of performance reasons.
</p>
<p>
There is only one non-conformant behavior when dealing with valid XML documents:
pugixml does not use information supplied in document type declaration for
parsing. This means that entities declared in DOCTYPE are not expanded, and
all attribute/PCDATA values are always processed in a uniform way that depends
only on parsing options.
</p>
<p>
As for rejecting invalid XML documents, there are a number of incompatibilities
with W3C specification, including:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Multiple attributes of the same node can have equal names.
</li>
<li class="listitem">
All non-ASCII characters are treated in the same way as symbols of English
alphabet, so some invalid tag names are not rejected.
</li>
<li class="listitem">
Attribute values which contain <code class="literal">&lt;</code> are not rejected.
</li>
<li class="listitem">
Invalid entity/character references are not rejected and are instead
left as is.
</li>
<li class="listitem">
Comment values can contain <code class="literal">--</code>.
</li>
<li class="listitem">
XML data is not required to begin with document declaration; additionally,
document declaration can appear after comments and other nodes.
</li>
<li class="listitem">
Invalid document type declarations are silently ignored in some cases.
</li>
</ul></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <b>Loading</b> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="dom.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="access.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
</body>
</html>

View file

@ -1,762 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Modifying document data</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="access.html" title="Accessing document data">
<link rel="next" href="saving.html" title="Saving document">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <b>Modifying</b> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="access.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="saving.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.modify"></a><a class="link" href="modify.html" title="Modifying document data"> Modifying document data</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="modify.html#manual.modify.nodedata"> Setting node data</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.attrdata"> Setting attribute data</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.add"> Adding nodes/attributes</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.remove"> Removing nodes/attributes</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.text"> Working with text contents</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.clone"> Cloning nodes/attributes</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.move"> Moving nodes</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.fragments"> Assembling document from fragments</a></span></dt>
</dl></div>
<p>
The document in pugixml is fully mutable: you can completely change the document
structure and modify the data of nodes/attributes. This section provides documentation
for the relevant functions. All functions take care of memory management and
structural integrity themselves, so they always result in structurally valid
tree - however, it is possible to create an invalid XML tree (for example,
by adding two attributes with the same name or by setting attribute/node name
to empty/invalid string). Tree modification is optimized for performance and
for memory consumption, so if you have enough memory you can create documents
from scratch with pugixml and later save them to file/stream instead of relying
on error-prone manual text writing and without too much overhead.
</p>
<p>
All member functions that change node/attribute data or structure are non-constant
and thus can not be called on constant handles. However, you can easily convert
constant handle to non-constant one by simple assignment: <code class="computeroutput"><span class="keyword">void</span>
<span class="identifier">foo</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">nc</span> <span class="special">=</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">}</span></code>, so const-correctness
here mainly provides additional documentation.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.modify.nodedata"></a><a class="link" href="modify.html#manual.modify.nodedata" title="Setting node data"> Setting node data</a>
</h3></div></div></div>
<a name="xml_node::set_name"></a><a name="xml_node::set_value"></a><p>
As discussed before, nodes can have name and value, both of which are strings.
Depending on node type, name or value may be absent. <a class="link" href="dom.html#node_document">node_document</a>
nodes do not have a name or value, <a class="link" href="dom.html#node_element">node_element</a>
and <a class="link" href="dom.html#node_declaration">node_declaration</a> nodes always
have a name but never have a value, <a class="link" href="dom.html#node_pcdata">node_pcdata</a>,
<a class="link" href="dom.html#node_cdata">node_cdata</a>, <a class="link" href="dom.html#node_comment">node_comment</a>
and <a class="link" href="dom.html#node_doctype">node_doctype</a> nodes never have a name
but always have a value (it may be empty though), <a class="link" href="dom.html#node_pi">node_pi</a>
nodes always have a name and a value (again, value may be empty). In order
to set node's name or value, you can use the following functions:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">set_name</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">set_value</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">rhs</span><span class="special">);</span>
</pre>
<p>
Both functions try to set the name/value to the specified string, and return
the operation result. The operation fails if the node can not have name or
value (for instance, when trying to call <code class="computeroutput"><span class="identifier">set_name</span></code>
on a <a class="link" href="dom.html#node_pcdata">node_pcdata</a> node), if the node handle
is null, or if there is insufficient memory to handle the request. The provided
string is copied into document managed memory and can be destroyed after
the function returns (for example, you can safely pass stack-allocated buffers
to these functions). The name/value content is not verified, so take care
to use only valid XML names, or the document may become malformed.
</p>
<p>
There is no equivalent of <a class="link" href="access.html#xml_node::child_value">child_value</a>
function for modifying text children of the node.
</p>
<p>
This is an example of setting node name and value (<a href="../samples/modify_base.cpp" target="_top">samples/modify_base.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"node"</span><span class="special">);</span>
<span class="comment">// change node name
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">set_name</span><span class="special">(</span><span class="string">"notnode"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", new node name: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// change comment text
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">last_child</span><span class="special">().</span><span class="identifier">set_value</span><span class="special">(</span><span class="string">"useless comment"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", new comment text: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">last_child</span><span class="special">().</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// we can't change value of the element or name of the comment
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span><span class="string">"1"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">last_child</span><span class="special">().</span><span class="identifier">set_name</span><span class="special">(</span><span class="string">"2"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.modify.attrdata"></a><a class="link" href="modify.html#manual.modify.attrdata" title="Setting attribute data"> Setting attribute data</a>
</h3></div></div></div>
<a name="xml_attribute::set_name"></a><a name="xml_attribute::set_value"></a><p>
All attributes have name and value, both of which are strings (value may
be empty). You can set them with the following functions:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">set_name</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">set_value</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">rhs</span><span class="special">);</span>
</pre>
<p>
Both functions try to set the name/value to the specified string, and return
the operation result. The operation fails if the attribute handle is null,
or if there is insufficient memory to handle the request. The provided string
is copied into document managed memory and can be destroyed after the function
returns (for example, you can safely pass stack-allocated buffers to these
functions). The name/value content is not verified, so take care to use only
valid XML names, or the document may become malformed.
</p>
<p>
In addition to string functions, several functions are provided for handling
attributes with numbers and booleans as values:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">set_value</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">set_value</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">set_value</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">set_value</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">set_value</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">set_value</span><span class="special">(</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="identifier">set_value</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span>
</pre>
<p>
The above functions convert the argument to string and then call the base
<code class="computeroutput"><span class="identifier">set_value</span></code> function. Integers
are converted to a decimal form, floating-point numbers are converted to
either decimal or scientific form, depending on the number magnitude, boolean
values are converted to either <code class="computeroutput"><span class="string">"true"</span></code>
or <code class="computeroutput"><span class="string">"false"</span></code>.
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
Number conversion functions depend on current C locale as set with <code class="computeroutput"><span class="identifier">setlocale</span></code>, so may generate unexpected
results if the locale is different from <code class="computeroutput"><span class="string">"C"</span></code>.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><span class="identifier">set_value</span></code> overloads with
<code class="computeroutput"><span class="keyword">long</span> <span class="keyword">long</span></code>
type are only available if your platform has reliable support for the type,
including string conversions.
</p></td></tr>
</table></div>
<a name="xml_attribute::assign"></a><p>
For convenience, all <code class="computeroutput"><span class="identifier">set_value</span></code>
functions have the corresponding assignment operators:
</p>
<pre class="programlisting"><span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">double</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">float</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">bool</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">xml_attribute</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span>
</pre>
<p>
These operators simply call the right <code class="computeroutput"><span class="identifier">set_value</span></code>
function and return the attribute they're called on; the return value of
<code class="computeroutput"><span class="identifier">set_value</span></code> is ignored, so
errors are ignored.
</p>
<p>
This is an example of setting attribute name and value (<a href="../samples/modify_base.cpp" target="_top">samples/modify_base.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute</span> <span class="identifier">attr</span> <span class="special">=</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"id"</span><span class="special">);</span>
<span class="comment">// change attribute name/value
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">set_name</span><span class="special">(</span><span class="string">"key"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span><span class="string">"345"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", new attribute: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"="</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// we can use numbers or booleans
</span><span class="identifier">attr</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span><span class="number">1.234</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"new attribute value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// we can also use assignment operators for more concise code
</span><span class="identifier">attr</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"final attribute value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.modify.add"></a><a class="link" href="modify.html#manual.modify.add" title="Adding nodes/attributes"> Adding nodes/attributes</a>
</h3></div></div></div>
<a name="xml_node::prepend_attribute"></a><a name="xml_node::append_attribute"></a><a name="xml_node::insert_attribute_after"></a><a name="xml_node::insert_attribute_before"></a><a name="xml_node::prepend_child"></a><a name="xml_node::append_child"></a><a name="xml_node::insert_child_after"></a><a name="xml_node::insert_child_before"></a><p>
Nodes and attributes do not exist without a document tree, so you can't create
them without adding them to some document. A node or attribute can be created
at the end of node/attribute list or before/after some other node:
</p>
<pre class="programlisting"><span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">prepend_attribute</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_attribute_after</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">);</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_attribute_before</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">append_child</span><span class="special">(</span><span class="identifier">xml_node_type</span> <span class="identifier">type</span> <span class="special">=</span> <span class="identifier">node_element</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">prepend_child</span><span class="special">(</span><span class="identifier">xml_node_type</span> <span class="identifier">type</span> <span class="special">=</span> <span class="identifier">node_element</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_child_after</span><span class="special">(</span><span class="identifier">xml_node_type</span> <span class="identifier">type</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_child_before</span><span class="special">(</span><span class="identifier">xml_node_type</span> <span class="identifier">type</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">append_child</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">prepend_child</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_child_after</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_child_before</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">append_attribute</span></code> and <code class="computeroutput"><span class="identifier">append_child</span></code> create a new node/attribute
at the end of the corresponding list of the node the method is called on;
<code class="computeroutput"><span class="identifier">prepend_attribute</span></code> and <code class="computeroutput"><span class="identifier">prepend_child</span></code> create a new node/attribute
at the beginning of the list; <code class="computeroutput"><span class="identifier">insert_attribute_after</span></code>,
<code class="computeroutput"><span class="identifier">insert_attribute_before</span></code>,
<code class="computeroutput"><span class="identifier">insert_child_after</span></code> and <code class="computeroutput"><span class="identifier">insert_attribute_before</span></code> add the node/attribute
before or after the specified node/attribute.
</p>
<p>
Attribute functions create an attribute with the specified name; you can
specify the empty name and change the name later if you want to. Node functions
with the <code class="computeroutput"><span class="identifier">type</span></code> argument create
the node with the specified type; since node type can't be changed, you have
to know the desired type beforehand. Also note that not all types can be
added as children; see below for clarification. Node functions with the
<code class="computeroutput"><span class="identifier">name</span></code> argument create the
element node (<a class="link" href="dom.html#node_element">node_element</a>) with the
specified name.
</p>
<p>
All functions return the handle to the created object on success, and null
handle on failure. There are several reasons for failure:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Adding fails if the target node is null;
</li>
<li class="listitem">
Only <a class="link" href="dom.html#node_element">node_element</a> nodes can contain
attributes, so attribute adding fails if node is not an element;
</li>
<li class="listitem">
Only <a class="link" href="dom.html#node_document">node_document</a> and <a class="link" href="dom.html#node_element">node_element</a>
nodes can contain children, so child node adding fails if the target
node is not an element or a document;
</li>
<li class="listitem">
<a class="link" href="dom.html#node_document">node_document</a> and <a class="link" href="dom.html#node_null">node_null</a>
nodes can not be inserted as children, so passing <a class="link" href="dom.html#node_document">node_document</a>
or <a class="link" href="dom.html#node_null">node_null</a> value as <code class="computeroutput"><span class="identifier">type</span></code> results in operation failure;
</li>
<li class="listitem">
<a class="link" href="dom.html#node_declaration">node_declaration</a> nodes can only
be added as children of the document node; attempt to insert declaration
node as a child of an element node fails;
</li>
<li class="listitem">
Adding node/attribute results in memory allocation, which may fail;
</li>
<li class="listitem">
Insertion functions fail if the specified node or attribute is null or
is not in the target node's children/attribute list.
</li>
</ul></div>
<p>
Even if the operation fails, the document remains in consistent state, but
the requested node/attribute is not added.
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
attribute() and child() functions do not add attributes or nodes to the
tree, so code like <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"id"</span><span class="special">)</span> <span class="special">=</span> <span class="number">123</span><span class="special">;</span></code> will not do anything if <code class="computeroutput"><span class="identifier">node</span></code> does not have an attribute with
name <code class="computeroutput"><span class="string">"id"</span></code>. Make sure
you're operating with existing attributes/nodes by adding them if necessary.
</p></td></tr>
</table></div>
<p>
This is an example of adding new attributes/nodes to the document (<a href="../samples/modify_add.cpp" target="_top">samples/modify_add.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// add node with some name
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">append_child</span><span class="special">(</span><span class="string">"node"</span><span class="special">);</span>
<span class="comment">// add description node with text child
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">descr</span> <span class="special">=</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">append_child</span><span class="special">(</span><span class="string">"description"</span><span class="special">);</span>
<span class="identifier">descr</span><span class="special">.</span><span class="identifier">append_child</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">node_pcdata</span><span class="special">).</span><span class="identifier">set_value</span><span class="special">(</span><span class="string">"Simple node"</span><span class="special">);</span>
<span class="comment">// add param node before the description
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">param</span> <span class="special">=</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">insert_child_before</span><span class="special">(</span><span class="string">"param"</span><span class="special">,</span> <span class="identifier">descr</span><span class="special">);</span>
<span class="comment">// add attributes to param node
</span><span class="identifier">param</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"name"</span><span class="special">)</span> <span class="special">=</span> <span class="string">"version"</span><span class="special">;</span>
<span class="identifier">param</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"value"</span><span class="special">)</span> <span class="special">=</span> <span class="number">1.1</span><span class="special">;</span>
<span class="identifier">param</span><span class="special">.</span><span class="identifier">insert_attribute_after</span><span class="special">(</span><span class="string">"type"</span><span class="special">,</span> <span class="identifier">param</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"name"</span><span class="special">))</span> <span class="special">=</span> <span class="string">"float"</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.modify.remove"></a><a class="link" href="modify.html#manual.modify.remove" title="Removing nodes/attributes"> Removing nodes/attributes</a>
</h3></div></div></div>
<a name="xml_node::remove_attribute"></a><a name="xml_node::remove_child"></a><p>
If you do not want your document to contain some node or attribute, you can
remove it with one of the following functions:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">remove_attribute</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">a</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">remove_child</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">);</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">remove_attribute</span></code> removes
the attribute from the attribute list of the node, and returns the operation
result. <code class="computeroutput"><span class="identifier">remove_child</span></code> removes
the child node with the entire subtree (including all descendant nodes and
attributes) from the document, and returns the operation result. Removing
fails if one of the following is true:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
The node the function is called on is null;
</li>
<li class="listitem">
The attribute/node to be removed is null;
</li>
<li class="listitem">
The attribute/node to be removed is not in the node's attribute/child
list.
</li>
</ul></div>
<p>
Removing the attribute or node invalidates all handles to the same underlying
object, and also invalidates all iterators pointing to the same object. Removing
node also invalidates all past-the-end iterators to its attribute or child
node list. Be careful to ensure that all such handles and iterators either
do not exist or are not used after the attribute/node is removed.
</p>
<p>
If you want to remove the attribute or child node by its name, two additional
helper functions are available:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">remove_attribute</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">remove_child</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span>
</pre>
<p>
These functions look for the first attribute or child with the specified
name, and then remove it, returning the result. If there is no attribute
or child with such name, the function returns <code class="computeroutput"><span class="keyword">false</span></code>;
if there are two nodes with the given name, only the first node is deleted.
If you want to delete all nodes with the specified name, you can use code
like this: <code class="computeroutput"><span class="keyword">while</span> <span class="special">(</span><span class="identifier">node</span><span class="special">.</span><span class="identifier">remove_child</span><span class="special">(</span><span class="string">"tool"</span><span class="special">))</span> <span class="special">;</span></code>.
</p>
<p>
This is an example of removing attributes/nodes from the document (<a href="../samples/modify_remove.cpp" target="_top">samples/modify_remove.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// remove description node with the whole subtree
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"node"</span><span class="special">);</span>
<span class="identifier">node</span><span class="special">.</span><span class="identifier">remove_child</span><span class="special">(</span><span class="string">"description"</span><span class="special">);</span>
<span class="comment">// remove id attribute
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">param</span> <span class="special">=</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"param"</span><span class="special">);</span>
<span class="identifier">param</span><span class="special">.</span><span class="identifier">remove_attribute</span><span class="special">(</span><span class="string">"value"</span><span class="special">);</span>
<span class="comment">// we can also remove nodes/attributes by handles
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute</span> <span class="identifier">id</span> <span class="special">=</span> <span class="identifier">param</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"name"</span><span class="special">);</span>
<span class="identifier">param</span><span class="special">.</span><span class="identifier">remove_attribute</span><span class="special">(</span><span class="identifier">id</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.modify.text"></a><a class="link" href="modify.html#manual.modify.text" title="Working with text contents"> Working with text contents</a>
</h3></div></div></div>
<p>
pugixml provides a special class, <code class="computeroutput"><span class="identifier">xml_text</span></code>,
to work with text contents stored as a value of some node, i.e. <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;&lt;</span><span class="identifier">description</span><span class="special">&gt;</span><span class="identifier">This</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">node</span><span class="special">&lt;/</span><span class="identifier">description</span><span class="special">&gt;&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span></code>.
Working with text objects to retrieve data is described in <a class="link" href="access.html#manual.access.text" title="Working with text contents">the
documentation for accessing document data</a>; this section describes
the modification interface of <code class="computeroutput"><span class="identifier">xml_text</span></code>.
</p>
<a name="xml_text::set"></a><p>
Once you have an <code class="computeroutput"><span class="identifier">xml_text</span></code>
object, you can set the text contents using the following function:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">rhs</span><span class="special">);</span>
</pre>
<p>
This function tries to set the contents to the specified string, and returns
the operation result. The operation fails if the text object was retrieved
from a node that can not have a value and is not an element node (i.e. it
is a <a class="link" href="dom.html#node_declaration">node_declaration</a> node), if the
text object is empty, or if there is insufficient memory to handle the request.
The provided string is copied into document managed memory and can be destroyed
after the function returns (for example, you can safely pass stack-allocated
buffers to this function). Note that if the text object was retrieved from
an element node, this function creates the PCDATA child node if necessary
(i.e. if the element node does not have a PCDATA/CDATA child already).
</p>
<a name="xml_text::set_value"></a><p>
In addition to a string function, several functions are provided for handling
text with numbers and booleans as contents:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span>
</pre>
<p>
The above functions convert the argument to string and then call the base
<code class="computeroutput"><span class="identifier">set</span></code> function. These functions
have the same semantics as similar <code class="computeroutput"><span class="identifier">xml_attribute</span></code>
functions. You can <a class="link" href="modify.html#xml_attribute::set_value">refer to documentation
for the attribute functions</a> for details.
</p>
<a name="xml_text::assign"></a><p>
For convenience, all <code class="computeroutput"><span class="identifier">set</span></code>
functions have the corresponding assignment operators:
</p>
<pre class="programlisting"><span class="identifier">xml_text</span><span class="special">&amp;</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_text</span><span class="special">&amp;</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_text</span><span class="special">&amp;</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_text</span><span class="special">&amp;</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">double</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_text</span><span class="special">&amp;</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">float</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_text</span><span class="special">&amp;</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">bool</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_text</span><span class="special">&amp;</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">xml_text</span><span class="special">&amp;</span> <span class="identifier">xml_text</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span><span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span>
</pre>
<p>
These operators simply call the right <code class="computeroutput"><span class="identifier">set</span></code>
function and return the attribute they're called on; the return value of
<code class="computeroutput"><span class="identifier">set</span></code> is ignored, so errors
are ignored.
</p>
<p>
This is an example of using <code class="computeroutput"><span class="identifier">xml_text</span></code>
object to modify text contents (<a href="../samples/text.cpp" target="_top">samples/text.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// change project version
</span><span class="identifier">project</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"version"</span><span class="special">).</span><span class="identifier">text</span><span class="special">()</span> <span class="special">=</span> <span class="number">1.2</span><span class="special">;</span>
<span class="comment">// add description element and set the contents
</span><span class="comment">// note that we do not have to explicitly add the node_pcdata child
</span><span class="identifier">project</span><span class="special">.</span><span class="identifier">append_child</span><span class="special">(</span><span class="string">"description"</span><span class="special">).</span><span class="identifier">text</span><span class="special">().</span><span class="identifier">set</span><span class="special">(</span><span class="string">"a test project"</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.modify.clone"></a><a class="link" href="modify.html#manual.modify.clone" title="Cloning nodes/attributes"> Cloning nodes/attributes</a>
</h3></div></div></div>
<a name="xml_node::prepend_copy"></a><a name="xml_node::append_copy"></a><a name="xml_node::insert_copy_after"></a><a name="xml_node::insert_copy_before"></a><p>
With the help of previously described functions, it is possible to create
trees with any contents and structure, including cloning the existing data.
However since this is an often needed operation, pugixml provides built-in
node/attribute cloning facilities. Since nodes and attributes do not exist
without a document tree, you can't create a standalone copy - you have to
immediately insert it somewhere in the tree. For this, you can use one of
the following functions:
</p>
<pre class="programlisting"><span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">append_copy</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">proto</span><span class="special">);</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">prepend_copy</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">proto</span><span class="special">);</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_copy_after</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">proto</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">);</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_copy_before</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">proto</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&amp;</span> <span class="identifier">attr</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">append_copy</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">proto</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">prepend_copy</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">proto</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_copy_after</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">proto</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_copy_before</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">proto</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
</pre>
<p>
These functions mirror the structure of <code class="computeroutput"><span class="identifier">append_child</span></code>,
<code class="computeroutput"><span class="identifier">prepend_child</span></code>, <code class="computeroutput"><span class="identifier">insert_child_before</span></code> and related functions
- they take the handle to the prototype object, which is to be cloned, insert
a new attribute/node at the appropriate place, and then copy the attribute
data or the whole node subtree to the new object. The functions return the
handle to the resulting duplicate object, or null handle on failure.
</p>
<p>
The attribute is copied along with the name and value; the node is copied
along with its type, name and value; additionally attribute list and all
children are recursively cloned, resulting in the deep subtree clone. The
prototype object can be a part of the same document, or a part of any other
document.
</p>
<p>
The failure conditions resemble those of <code class="computeroutput"><span class="identifier">append_child</span></code>,
<code class="computeroutput"><span class="identifier">insert_child_before</span></code> and related
functions, <a class="link" href="modify.html#xml_node::append_child">consult their documentation
for more information</a>. There are additional caveats specific to cloning
functions:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Cloning null handles results in operation failure;
</li>
<li class="listitem">
Node cloning starts with insertion of the node of the same type as that
of the prototype; for this reason, cloning functions can not be directly
used to clone entire documents, since <a class="link" href="dom.html#node_document">node_document</a>
is not a valid insertion type. The example below provides a workaround.
</li>
<li class="listitem">
It is possible to copy a subtree as a child of some node inside this
subtree, i.e. <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">append_copy</span><span class="special">(</span><span class="identifier">node</span><span class="special">.</span><span class="identifier">parent</span><span class="special">().</span><span class="identifier">parent</span><span class="special">());</span></code>.
This is a valid operation, and it results in a clone of the subtree in
the state before cloning started, i.e. no infinite recursion takes place.
</li>
</ul></div>
<p>
This is an example with one possible implementation of include tags in XML
(<a href="../samples/include.cpp" target="_top">samples/include.cpp</a>). It illustrates
node cloning and usage of other document modification functions:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">load_preprocess</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span><span class="special">&amp;</span> <span class="identifier">doc</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">path</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">preprocess</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">child</span> <span class="special">=</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">();</span> <span class="identifier">child</span><span class="special">;</span> <span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">child</span><span class="special">.</span><span class="identifier">type</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">node_pi</span> <span class="special">&amp;&amp;</span> <span class="identifier">strcmp</span><span class="special">(</span><span class="identifier">child</span><span class="special">.</span><span class="identifier">name</span><span class="special">(),</span> <span class="string">"include"</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">include</span> <span class="special">=</span> <span class="identifier">child</span><span class="special">;</span>
<span class="comment">// load new preprocessed document (note: ideally this should handle relative paths)
</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">path</span> <span class="special">=</span> <span class="identifier">include</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">load_preprocess</span><span class="special">(</span><span class="identifier">doc</span><span class="special">,</span> <span class="identifier">path</span><span class="special">))</span> <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span>
<span class="comment">// insert the comment marker above include directive
</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">insert_child_before</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">node_comment</span><span class="special">,</span> <span class="identifier">include</span><span class="special">).</span><span class="identifier">set_value</span><span class="special">(</span><span class="identifier">path</span><span class="special">);</span>
<span class="comment">// copy the document above the include directive (this retains the original order!)
</span> <span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">ic</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">();</span> <span class="identifier">ic</span><span class="special">;</span> <span class="identifier">ic</span> <span class="special">=</span> <span class="identifier">ic</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">node</span><span class="special">.</span><span class="identifier">insert_copy_before</span><span class="special">(</span><span class="identifier">ic</span><span class="special">,</span> <span class="identifier">include</span><span class="special">);</span>
<span class="special">}</span>
<span class="comment">// remove the include node and move to the next child
</span> <span class="identifier">child</span> <span class="special">=</span> <span class="identifier">child</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">();</span>
<span class="identifier">node</span><span class="special">.</span><span class="identifier">remove_child</span><span class="special">(</span><span class="identifier">include</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">preprocess</span><span class="special">(</span><span class="identifier">child</span><span class="special">))</span> <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span>
<span class="identifier">child</span> <span class="special">=</span> <span class="identifier">child</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">();</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">bool</span> <span class="identifier">load_preprocess</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span><span class="special">&amp;</span> <span class="identifier">doc</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">path</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_file</span><span class="special">(</span><span class="identifier">path</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_default</span> <span class="special">|</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">parse_pi</span><span class="special">);</span> <span class="comment">// for &lt;?include?&gt;
</span>
<span class="keyword">return</span> <span class="identifier">result</span> <span class="special">?</span> <span class="identifier">preprocess</span><span class="special">(</span><span class="identifier">doc</span><span class="special">)</span> <span class="special">:</span> <span class="keyword">false</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.modify.move"></a><a class="link" href="modify.html#manual.modify.move" title="Moving nodes"> Moving nodes</a>
</h3></div></div></div>
<a name="xml_node::prepend_move"></a><a name="xml_node::append_move"></a><a name="xml_node::insert_move_after"></a><a name="xml_node::insert_move_before"></a><p>
Sometimes instead of cloning a node you need to move an existing node to
a different position in a tree. This can be accomplished by copying the node
and removing the original; however, this is expensive since it results in
a lot of extra operations. For moving nodes within the same document tree,
you can use of the following functions instead:
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">append_move</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">moved</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">prepend_move</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">moved</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_move_after</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">moved</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
<span class="identifier">xml_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">insert_move_before</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">moved</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">);</span>
</pre>
<p>
These functions mirror the structure of <code class="computeroutput"><span class="identifier">append_copy</span></code>,
<code class="computeroutput"><span class="identifier">prepend_copy</span></code>, <code class="computeroutput"><span class="identifier">insert_copy_before</span></code> and <code class="computeroutput"><span class="identifier">insert_copy_after</span></code>
- they take the handle to the moved object and move it to the appropriate
place with all attributes and/or child nodes. The functions return the handle
to the resulting object (which is the same as the moved object), or null
handle on failure.
</p>
<p>
The failure conditions resemble those of <code class="computeroutput"><span class="identifier">append_child</span></code>,
<code class="computeroutput"><span class="identifier">insert_child_before</span></code> and related
functions, <a class="link" href="modify.html#xml_node::append_child">consult their documentation
for more information</a>. There are additional caveats specific to moving
functions:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Moving null handles results in operation failure;
</li>
<li class="listitem">
Moving is only possible for nodes that belong to the same document; attempting
to move nodes between documents will fail.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">insert_move_after</span></code> and
<code class="computeroutput"><span class="identifier">insert_move_before</span></code> functions
fail if the moved node is the same as the <code class="computeroutput"><span class="identifier">node</span></code>
argument (this operation would be a no-op otherwise).
</li>
<li class="listitem">
It is impossible to move a subtree to a child of some node inside this
subtree, i.e. <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">append_move</span><span class="special">(</span><span class="identifier">node</span><span class="special">.</span><span class="identifier">parent</span><span class="special">().</span><span class="identifier">parent</span><span class="special">());</span></code>
will fail.
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.modify.fragments"></a><a class="link" href="modify.html#manual.modify.fragments" title="Assembling document from fragments"> Assembling document from fragments</a>
</h3></div></div></div>
<a name="xml_node::append_buffer"></a><p>
pugixml provides several ways to assemble an XML document from other XML
documents. Assuming there is a set of document fragments, represented as
in-memory buffers, the implementation choices are as follows:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Use a temporary document to parse the data from a string, then clone
the nodes to a destination node. For example:
</li></ul></div>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">append_fragment</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">target</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_buffer</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">size</span><span class="special">))</span> <span class="keyword">return</span> <span class="keyword">false</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">child</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">();</span> <span class="identifier">child</span><span class="special">;</span> <span class="identifier">child</span> <span class="special">=</span> <span class="identifier">child</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">())</span>
<span class="identifier">target</span><span class="special">.</span><span class="identifier">append_copy</span><span class="special">(</span><span class="identifier">child</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Cache the parsing step - instead of keeping in-memory buffers, keep document
objects that already contain the parsed fragment:
</li></ul></div>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">append_fragment</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">target</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span><span class="special">&amp;</span> <span class="identifier">cached_fragment</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">child</span> <span class="special">=</span> <span class="identifier">cached_fragment</span><span class="special">.</span><span class="identifier">first_child</span><span class="special">();</span> <span class="identifier">child</span><span class="special">;</span> <span class="identifier">child</span> <span class="special">=</span> <span class="identifier">child</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">())</span>
<span class="identifier">target</span><span class="special">.</span><span class="identifier">append_copy</span><span class="special">(</span><span class="identifier">child</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Use xml_node::append_buffer directly:
</li></ul></div>
<pre class="programlisting"><span class="identifier">xml_parse_result</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">append_buffer</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">contents</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">);</span>
</pre>
<p>
The first method is more convenient, but slower than the other two. The relative
performance of <code class="computeroutput"><span class="identifier">append_copy</span></code>
and <code class="computeroutput"><span class="identifier">append_buffer</span></code> depends
on the buffer format - usually <code class="computeroutput"><span class="identifier">append_buffer</span></code>
is faster if the buffer is in native encoding (UTF-8 or wchar_t, depending
on <code class="computeroutput"><span class="identifier">PUGIXML_WCHAR_MODE</span></code>). At
the same time it might be less efficient in terms of memory usage - the implementation
makes a copy of the provided buffer, and the copy has the same lifetime as
the document - the memory used by that copy will be reclaimed after the document
is destroyed, but no sooner. Even deleting all nodes in the document, including
the appended ones, won't reclaim the memory.
</p>
<p>
<code class="computeroutput"><span class="identifier">append_buffer</span></code> behaves in
the same way as <a class="link" href="loading.html#xml_document::load_buffer">xml_document::load_buffer</a>
- the input buffer is a byte buffer, with size in bytes; the buffer is not
modified and can be freed after the function returns.
</p>
<a name="status_append_invalid_root"></a><p>
Since <code class="computeroutput"><span class="identifier">append_buffer</span></code> needs
to append child nodes to the current node, it only works if the current node
is either document or element node. Calling <code class="computeroutput"><span class="identifier">append_buffer</span></code>
on a node with any other type results in an error with <code class="computeroutput"><span class="identifier">status_append_invalid_root</span></code>
status.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <b>Modifying</b> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="access.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="saving.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
</body>
</html>

View file

@ -1,543 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Saving document</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="modify.html" title="Modifying document data">
<link rel="next" href="xpath.html" title="XPath">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <b>Saving</b> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="modify.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="xpath.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.saving"></a><a class="link" href="saving.html" title="Saving document"> Saving document</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="saving.html#manual.saving.file"> Saving document to a file</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.stream"> Saving document to C++ IOstreams</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.writer"> Saving document via writer interface</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.subtree"> Saving a single subtree</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.options"> Output options</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.encoding"> Encodings</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.declaration"> Customizing document declaration</a></span></dt>
</dl></div>
<p>
Often after creating a new document or loading the existing one and processing
it, it is necessary to save the result back to file. Also it is occasionally
useful to output the whole document or a subtree to some stream; use cases
include debug printing, serialization via network or other text-oriented medium,
etc. pugixml provides several functions to output any subtree of the document
to a file, stream or another generic transport interface; these functions allow
to customize the output format (see <a class="xref" href="saving.html#manual.saving.options" title="Output options"> Output options</a>), and also perform
necessary encoding conversions (see <a class="xref" href="saving.html#manual.saving.encoding" title="Encodings"> Encodings</a>). This section documents
the relevant functionality.
</p>
<p>
Before writing to the destination the node/attribute data is properly formatted
according to the node type; all special XML symbols, such as &lt; and &amp;,
are properly escaped (unless <a class="link" href="saving.html#format_no_escapes">format_no_escapes</a>
flag is set). In order to guard against forgotten node/attribute names, empty
node/attribute names are printed as <code class="computeroutput"><span class="string">":anonymous"</span></code>.
For well-formed output, make sure all node and attribute names are set to meaningful
values.
</p>
<p>
CDATA sections with values that contain <code class="computeroutput"><span class="string">"]]&gt;"</span></code>
are split into several sections as follows: section with value <code class="computeroutput"><span class="string">"pre]]&gt;post"</span></code> is written as <code class="computeroutput"><span class="special">&lt;![</span><span class="identifier">CDATA</span><span class="special">[</span><span class="identifier">pre</span><span class="special">]]]]&gt;&lt;![</span><span class="identifier">CDATA</span><span class="special">[&gt;</span><span class="identifier">post</span><span class="special">]]&gt;</span></code>.
While this alters the structure of the document (if you load the document after
saving it, there will be two CDATA sections instead of one), this is the only
way to escape CDATA contents.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.file"></a><a class="link" href="saving.html#manual.saving.file" title="Saving document to a file"> Saving document to a file</a>
</h3></div></div></div>
<a name="xml_document::save_file"></a><a name="xml_document::save_file_wide"></a><p>
If you want to save the whole document to a file, you can use one of the
following functions:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save_file</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">path</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save_file</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">wchar_t</span><span class="special">*</span> <span class="identifier">path</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
These functions accept file path as its first argument, and also three optional
arguments, which specify indentation and other output options (see <a class="xref" href="saving.html#manual.saving.options" title="Output options"> Output options</a>)
and output data encoding (see <a class="xref" href="saving.html#manual.saving.encoding" title="Encodings"> Encodings</a>). The path has the target
operating system format, so it can be a relative or absolute one, it should
have the delimiters of the target system, it should have the exact case if
the target file system is case-sensitive, etc.
</p>
<p>
File path is passed to the system file opening function as is in case of
the first function (which accepts <code class="computeroutput"><span class="keyword">const</span>
<span class="keyword">char</span><span class="special">*</span> <span class="identifier">path</span></code>); the second function either uses
a special file opening function if it is provided by the runtime library
or converts the path to UTF-8 and uses the system file opening function.
</p>
<a name="xml_writer_file"></a><p>
<code class="computeroutput"><span class="identifier">save_file</span></code> opens the target
file for writing, outputs the requested header (by default a document declaration
is output, unless the document already has one), and then saves the document
contents. If the file could not be opened, the function returns <code class="computeroutput"><span class="keyword">false</span></code>. Calling <code class="computeroutput"><span class="identifier">save_file</span></code>
is equivalent to creating an <code class="computeroutput"><span class="identifier">xml_writer_file</span></code>
object with <code class="computeroutput"><span class="identifier">FILE</span><span class="special">*</span></code>
handle as the only constructor argument and then calling <code class="computeroutput"><span class="identifier">save</span></code>;
see <a class="xref" href="saving.html#manual.saving.writer" title="Saving document via writer interface"> Saving document via writer interface</a> for writer interface details.
</p>
<p>
This is a simple example of saving XML document to file (<a href="../samples/save_file.cpp" target="_top">samples/save_file.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// save document to file
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Saving result: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">save_file</span><span class="special">(</span><span class="string">"save_file_output.xml"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.stream"></a><a class="link" href="saving.html#manual.saving.stream" title="Saving document to C++ IOstreams"> Saving document to C++ IOstreams</a>
</h3></div></div></div>
<a name="xml_document::save_stream"></a><p>
To enhance interoperability pugixml provides functions for saving document
to any object which implements C++ <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span></code>
interface. This allows you to save documents to any standard C++ stream (i.e.
file stream) or any third-party compliant implementation (i.e. Boost Iostreams).
Most notably, this allows for easy debug output, since you can use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code>
stream as saving target. There are two functions, one works with narrow character
streams, another handles wide character ones:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">stream</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">wostream</span><span class="special">&amp;</span> <span class="identifier">stream</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">save</span></code> with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span></code>
argument saves the document to the stream in the same way as <code class="computeroutput"><span class="identifier">save_file</span></code> (i.e. with requested header and
with encoding conversions). On the other hand, <code class="computeroutput"><span class="identifier">save</span></code>
with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstream</span></code> argument saves the document to
the wide stream with <a class="link" href="loading.html#encoding_wchar">encoding_wchar</a>
encoding. Because of this, using <code class="computeroutput"><span class="identifier">save</span></code>
with wide character streams requires careful (usually platform-specific)
stream setup (i.e. using the <code class="computeroutput"><span class="identifier">imbue</span></code>
function). Generally use of wide streams is discouraged, however it provides
you with the ability to save documents to non-Unicode encodings, i.e. you
can save Shift-JIS encoded data if you set the correct locale.
</p>
<a name="xml_writer_stream"></a><p>
Calling <code class="computeroutput"><span class="identifier">save</span></code> with stream
target is equivalent to creating an <code class="computeroutput"><span class="identifier">xml_writer_stream</span></code>
object with stream as the only constructor argument and then calling <code class="computeroutput"><span class="identifier">save</span></code>; see <a class="xref" href="saving.html#manual.saving.writer" title="Saving document via writer interface"> Saving document via writer interface</a> for writer
interface details.
</p>
<p>
This is a simple example of saving XML document to standard output (<a href="../samples/save_stream.cpp" target="_top">samples/save_stream.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// save document to standard output
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Document:\n"</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.writer"></a><a class="link" href="saving.html#manual.saving.writer" title="Saving document via writer interface"> Saving document via writer interface</a>
</h3></div></div></div>
<a name="xml_document::save"></a><a name="xml_writer"></a><a name="xml_writer::write"></a><p>
All of the above saving functions are implemented in terms of writer interface.
This is a simple interface with a single function, which is called several
times during output process with chunks of document data as input:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">xml_writer</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">write</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">void</span> <span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">xml_writer</span><span class="special">&amp;</span> <span class="identifier">writer</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
In order to output the document via some custom transport, for example sockets,
you should create an object which implements <code class="computeroutput"><span class="identifier">xml_writer</span></code>
interface and pass it to <code class="computeroutput"><span class="identifier">save</span></code>
function. <code class="computeroutput"><span class="identifier">xml_writer</span><span class="special">::</span><span class="identifier">write</span></code> function is called with a buffer
as an input, where <code class="computeroutput"><span class="identifier">data</span></code> points
to buffer start, and <code class="computeroutput"><span class="identifier">size</span></code>
is equal to the buffer size in bytes. <code class="computeroutput"><span class="identifier">write</span></code>
implementation must write the buffer to the transport; it can not save the
passed buffer pointer, as the buffer contents will change after <code class="computeroutput"><span class="identifier">write</span></code> returns. The buffer contains the
chunk of document data in the desired encoding.
</p>
<p>
<code class="computeroutput"><span class="identifier">write</span></code> function is called
with relatively large blocks (size is usually several kilobytes, except for
the last block that may be small), so there is often no need for additional
buffering in the implementation.
</p>
<p>
This is a simple example of custom writer for saving document data to STL
string (<a href="../samples/save_custom_writer.cpp" target="_top">samples/save_custom_writer.cpp</a>);
read the sample code for more complex examples:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">xml_string_writer</span><span class="special">:</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_writer</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span><span class="special">;</span>
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">write</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">result</span><span class="special">.</span><span class="identifier">append</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">size</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.subtree"></a><a class="link" href="saving.html#manual.saving.subtree" title="Saving a single subtree"> Saving a single subtree</a>
</h3></div></div></div>
<a name="xml_node::print"></a><a name="xml_node::print_stream"></a><p>
While the previously described functions save the whole document to the destination,
it is easy to save a single subtree. The following functions are provided:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">depth</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">wostream</span><span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">depth</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">xml_writer</span><span class="special">&amp;</span> <span class="identifier">writer</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">indent</span> <span class="special">=</span> <span class="string">"\t"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">flags</span> <span class="special">=</span> <span class="identifier">format_default</span><span class="special">,</span> <span class="identifier">xml_encoding</span> <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">depth</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
These functions have the same arguments with the same meaning as the corresponding
<code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span></code> functions, and allow you to save the
subtree to either a C++ IOstream or to any object that implements <code class="computeroutput"><span class="identifier">xml_writer</span></code> interface.
</p>
<p>
Saving a subtree differs from saving the whole document: the process behaves
as if <a class="link" href="saving.html#format_write_bom">format_write_bom</a> is off, and
<a class="link" href="saving.html#format_no_declaration">format_no_declaration</a> is on,
even if actual values of the flags are different. This means that BOM is
not written to the destination, and document declaration is only written
if it is the node itself or is one of node's children. Note that this also
holds if you're saving a document; this example (<a href="../samples/save_subtree.cpp" target="_top">samples/save_subtree.cpp</a>)
illustrates the difference:
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// get a test document
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="string">"&lt;foo bar='baz'&gt;&lt;call&gt;hey&lt;/call&gt;&lt;/foo&gt;"</span><span class="special">);</span>
<span class="comment">// print document to standard output (prints &lt;?xml version="1.0"?&gt;&lt;foo bar="baz"&gt;&lt;call&gt;hey&lt;/call&gt;&lt;/foo&gt;)
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">""</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// print document to standard output as a regular node (prints &lt;foo bar="baz"&gt;&lt;call&gt;hey&lt;/call&gt;&lt;/foo&gt;)
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">""</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// print a subtree to standard output (prints &lt;call&gt;hey&lt;/call&gt;)
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"foo"</span><span class="special">).</span><span class="identifier">child</span><span class="special">(</span><span class="string">"call"</span><span class="special">).</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">""</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.options"></a><a class="link" href="saving.html#manual.saving.options" title="Output options"> Output options</a>
</h3></div></div></div>
<p>
All saving functions accept the optional parameter <code class="computeroutput"><span class="identifier">flags</span></code>.
This is a bitmask that customizes the output format; you can select the way
the document nodes are printed and select the needed additional information
that is output before the document contents.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
You should use the usual bitwise arithmetics to manipulate the bitmask:
to enable a flag, use <code class="computeroutput"><span class="identifier">mask</span> <span class="special">|</span> <span class="identifier">flag</span></code>;
to disable a flag, use <code class="computeroutput"><span class="identifier">mask</span> <span class="special">&amp;</span> <span class="special">~</span><span class="identifier">flag</span></code>.
</p></td></tr>
</table></div>
<p>
These flags control the resulting tree contents:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a name="format_indent"></a><code class="literal">format_indent</code> determines if all nodes
should be indented with the indentation string (this is an additional
parameter for all saving functions, and is <code class="computeroutput"><span class="string">"\t"</span></code>
by default). If this flag is on, before every node the indentation string
is output several times, where the amount of indentation depends on the
node's depth relative to the output subtree. This flag has no effect
if <a class="link" href="saving.html#format_raw">format_raw</a> is enabled. This flag
is <span class="bold"><strong>on</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="format_raw"></a><code class="literal">format_raw</code> switches between formatted and
raw output. If this flag is on, the nodes are not indented in any way,
and also no newlines that are not part of document text are printed.
Raw mode can be used for serialization where the result is not intended
to be read by humans; also it can be useful if the document was parsed
with <a class="link" href="loading.html#parse_ws_pcdata">parse_ws_pcdata</a> flag, to
preserve the original document formatting as much as possible. This flag
is <span class="bold"><strong>off</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="format_no_escapes"></a><code class="literal">format_no_escapes</code> disables output
escaping for attribute values and PCDATA contents. If this flag is off,
special symbols (', &amp;, &lt;, &gt;) and all non-printable characters
(those with codepoint values less than 32) are converted to XML escape
sequences (i.e. &amp;amp;) during output. If this flag is on, no text
processing is performed; therefore, output XML can be malformed if output
contents contains invalid symbols (i.e. having a stray &lt; in the PCDATA
will make the output malformed). This flag is <span class="bold"><strong>off</strong></span>
by default.
</li>
</ul></div>
<p>
These flags control the additional output information:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a name="format_no_declaration"></a><code class="literal">format_no_declaration</code> disables
default node declaration output. By default, if the document is saved
via <code class="computeroutput"><span class="identifier">save</span></code> or <code class="computeroutput"><span class="identifier">save_file</span></code> function, and it does not
have any document declaration, a default declaration is output before
the document contents. Enabling this flag disables this declaration.
This flag has no effect in <code class="computeroutput"><span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span></code>
functions: they never output the default declaration. This flag is <span class="bold"><strong>off</strong></span> by default. <br><br>
</li>
<li class="listitem">
<a name="format_write_bom"></a><code class="literal">format_write_bom</code> enables Byte Order
Mark (BOM) output. By default, no BOM is output, so in case of non UTF-8
encodings the resulting document's encoding may not be recognized by
some parsers and text editors, if they do not implement sophisticated
encoding detection. Enabling this flag adds an encoding-specific BOM
to the output. This flag has no effect in <code class="computeroutput"><span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span></code>
functions: they never output the BOM. This flag is <span class="bold"><strong>off</strong></span>
by default.
</li>
<li class="listitem">
<a name="format_save_file_text"></a><code class="literal">format_save_file_text</code> changes
the file mode when using <code class="computeroutput"><span class="identifier">save_file</span></code>
function. By default, file is opened in binary mode, which means that
the output file will contain platform-independent newline \n (ASCII 10).
If this flag is on, file is opened in text mode, which on some systems
changes the newline format (i.e. on Windows you can use this flag to
output XML documents with \r\n (ASCII 13 10) newlines. This flag is
<span class="bold"><strong>off</strong></span> by default.
</li>
</ul></div>
<p>
Additionally, there is one predefined option mask:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
<a name="format_default"></a><code class="literal">format_default</code> is the default set of
flags, i.e. it has all options set to their default values. It sets formatted
output with indentation, without BOM and with default node declaration,
if necessary.
</li></ul></div>
<p>
This is an example that shows the outputs of different output options (<a href="../samples/save_options.cpp" target="_top">samples/save_options.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// get a test document
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="string">"&lt;foo bar='baz'&gt;&lt;call&gt;hey&lt;/call&gt;&lt;/foo&gt;"</span><span class="special">);</span>
<span class="comment">// default options; prints
</span><span class="comment">// &lt;?xml version="1.0"?&gt;
</span><span class="comment">// &lt;foo bar="baz"&gt;
</span><span class="comment">// &lt;call&gt;hey&lt;/call&gt;
</span><span class="comment">// &lt;/foo&gt;
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// default options with custom indentation string; prints
</span><span class="comment">// &lt;?xml version="1.0"?&gt;
</span><span class="comment">// &lt;foo bar="baz"&gt;
</span><span class="comment">// --&lt;call&gt;hey&lt;/call&gt;
</span><span class="comment">// &lt;/foo&gt;
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">"--"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// default options without indentation; prints
</span><span class="comment">// &lt;?xml version="1.0"?&gt;
</span><span class="comment">// &lt;foo bar="baz"&gt;
</span><span class="comment">// &lt;call&gt;hey&lt;/call&gt;
</span><span class="comment">// &lt;/foo&gt;
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">"\t"</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_default</span> <span class="special">&amp;</span> <span class="special">~</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_indent</span><span class="special">);</span> <span class="comment">// can also pass "" instead of indentation string for the same effect
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// raw output; prints
</span><span class="comment">// &lt;?xml version="1.0"?&gt;&lt;foo bar="baz"&gt;&lt;call&gt;hey&lt;/call&gt;&lt;/foo&gt;
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">"\t"</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// raw output without declaration; prints
</span><span class="comment">// &lt;foo bar="baz"&gt;&lt;call&gt;hey&lt;/call&gt;&lt;/foo&gt;
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">"\t"</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_raw</span> <span class="special">|</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">format_no_declaration</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.encoding"></a><a class="link" href="saving.html#manual.saving.encoding" title="Encodings"> Encodings</a>
</h3></div></div></div>
<p>
pugixml supports all popular Unicode encodings (UTF-8, UTF-16 (big and little
endian), UTF-32 (big and little endian); UCS-2 is naturally supported since
it's a strict subset of UTF-16) and handles all encoding conversions during
output. The output encoding is set via the <code class="computeroutput"><span class="identifier">encoding</span></code>
parameter of saving functions, which is of type <code class="computeroutput"><span class="identifier">xml_encoding</span></code>.
The possible values for the encoding are documented in <a class="xref" href="loading.html#manual.loading.encoding" title="Encodings"> Encodings</a>;
the only flag that has a different meaning is <code class="computeroutput"><span class="identifier">encoding_auto</span></code>.
</p>
<p>
While all other flags set the exact encoding, <code class="computeroutput"><span class="identifier">encoding_auto</span></code>
is meant for automatic encoding detection. The automatic detection does not
make sense for output encoding, since there is usually nothing to infer the
actual encoding from, so here <code class="computeroutput"><span class="identifier">encoding_auto</span></code>
means UTF-8 encoding, which is the most popular encoding for XML data storage.
This is also the default value of output encoding; specify another value
if you do not want UTF-8 encoded output.
</p>
<p>
Also note that wide stream saving functions do not have <code class="computeroutput"><span class="identifier">encoding</span></code>
argument and always assume <a class="link" href="loading.html#encoding_wchar">encoding_wchar</a>
encoding.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The current behavior for Unicode conversion is to skip all invalid UTF
sequences during conversion. This behavior should not be relied upon; if
your node/attribute names do not contain any valid UTF sequences, they
may be output as if they are empty, which will result in malformed XML
document.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.saving.declaration"></a><a class="link" href="saving.html#manual.saving.declaration" title="Customizing document declaration"> Customizing document declaration</a>
</h3></div></div></div>
<p>
When you are saving the document using <code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save_file</span><span class="special">()</span></code>, a default XML document declaration is
output, if <code class="computeroutput"><span class="identifier">format_no_declaration</span></code>
is not specified and if the document does not have a declaration node. However,
the default declaration is not customizable. If you want to customize the
declaration output, you need to create the declaration node yourself.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
By default the declaration node is not added to the document during parsing.
If you just need to preserve the original declaration node, you have to
add the flag <a class="link" href="loading.html#parse_declaration">parse_declaration</a>
to the parsing flags; the resulting document will contain the original
declaration node, which will be output during saving.
</p></td></tr>
</table></div>
<p>
Declaration node is a node with type <a class="link" href="dom.html#node_declaration">node_declaration</a>;
it behaves like an element node in that it has attributes with values (but
it does not have child nodes). Therefore setting custom version, encoding
or standalone declaration involves adding attributes and setting attribute
values.
</p>
<p>
This is an example that shows how to create a custom declaration node (<a href="../samples/save_declaration.cpp" target="_top">samples/save_declaration.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// get a test document
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="string">"&lt;foo bar='baz'&gt;&lt;call&gt;hey&lt;/call&gt;&lt;/foo&gt;"</span><span class="special">);</span>
<span class="comment">// add a custom declaration node
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">decl</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">prepend_child</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">node_declaration</span><span class="special">);</span>
<span class="identifier">decl</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"version"</span><span class="special">)</span> <span class="special">=</span> <span class="string">"1.0"</span><span class="special">;</span>
<span class="identifier">decl</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"encoding"</span><span class="special">)</span> <span class="special">=</span> <span class="string">"UTF-8"</span><span class="special">;</span>
<span class="identifier">decl</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"standalone"</span><span class="special">)</span> <span class="special">=</span> <span class="string">"no"</span><span class="special">;</span>
<span class="comment">// &lt;?xml version="1.0" encoding="UTF-8" standalone="no"?&gt;
</span><span class="comment">// &lt;foo bar="baz"&gt;
</span><span class="comment">// &lt;call&gt;hey&lt;/call&gt;
</span><span class="comment">// &lt;/foo&gt;
</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <b>Saving</b> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="modify.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="xpath.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
</body>
</html>

View file

@ -1,163 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Table of Contents</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="apiref.html" title="API Reference">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<b>Table of Contents</b>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="apiref.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.toc"></a><a class="link" href="toc.html" title="Table of Contents"> Table of Contents</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="../manual.html#manual.overview"> Overview</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="../manual.html#manual.overview.introduction"> Introduction</a></span></dt>
<dt><span class="section"><a href="../manual.html#manual.overview.feedback"> Feedback</a></span></dt>
<dt><span class="section"><a href="../manual.html#manual.overview.thanks"> Acknowledgments</a></span></dt>
<dt><span class="section"><a href="../manual.html#manual.overview.license"> License</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="install.html"> Installation</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="install.html#manual.install.getting"> Getting pugixml</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="install.html#manual.install.getting.source"> Source distributions</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.getting.git"> Git repository</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.getting.subversion"> Subversion repository</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="install.html#manual.install.building"> Building pugixml</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="install.html#manual.install.building.embed"> Building pugixml as
a part of another static library/executable</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.building.static"> Building pugixml as
a standalone static library</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.building.shared"> Building pugixml as
a standalone shared library</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.building.header"> Using pugixml in header-only
mode</a></span></dt>
<dt><span class="section"><a href="install.html#manual.install.building.config"> Additional configuration
options</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="install.html#manual.install.portability"> Portability</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="dom.html"> Document object model</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="dom.html#manual.dom.tree"> Tree structure</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.cpp"> C++ interface</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.unicode"> Unicode interface</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.thread"> Thread-safety guarantees</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.exception"> Exception guarantees</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.memory"> Memory management</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="dom.html#manual.dom.memory.custom"> Custom memory allocation/deallocation
functions</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.memory.tuning"> Memory consumption tuning</a></span></dt>
<dt><span class="section"><a href="dom.html#manual.dom.memory.internals"> Document memory management
internals</a></span></dt>
</dl></dd>
</dl></dd>
<dt><span class="section"><a href="loading.html"> Loading document</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="loading.html#manual.loading.file"> Loading document from file</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.memory"> Loading document from memory</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.stream"> Loading document from C++ IOstreams</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.errors"> Handling parsing errors</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.options"> Parsing options</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.encoding"> Encodings</a></span></dt>
<dt><span class="section"><a href="loading.html#manual.loading.w3c"> Conformance to W3C specification</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="access.html"> Accessing document data</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="access.html#manual.access.basic"> Basic traversal functions</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.nodedata"> Getting node data</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.attrdata"> Getting attribute data</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.contents"> Contents-based traversal functions</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.rangefor"> Range-based for-loop support</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.iterators"> Traversing node/attribute lists
via iterators</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.walker"> Recursive traversal with xml_tree_walker</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.predicate"> Searching for nodes/attributes
with predicates</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.text"> Working with text contents</a></span></dt>
<dt><span class="section"><a href="access.html#manual.access.misc"> Miscellaneous functions</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="modify.html"> Modifying document data</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="modify.html#manual.modify.nodedata"> Setting node data</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.attrdata"> Setting attribute data</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.add"> Adding nodes/attributes</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.remove"> Removing nodes/attributes</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.text"> Working with text contents</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.clone"> Cloning nodes/attributes</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.move"> Moving nodes</a></span></dt>
<dt><span class="section"><a href="modify.html#manual.modify.fragments"> Assembling document from fragments</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="saving.html"> Saving document</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="saving.html#manual.saving.file"> Saving document to a file</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.stream"> Saving document to C++ IOstreams</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.writer"> Saving document via writer interface</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.subtree"> Saving a single subtree</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.options"> Output options</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.encoding"> Encodings</a></span></dt>
<dt><span class="section"><a href="saving.html#manual.saving.declaration"> Customizing document declaration</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="xpath.html"> XPath</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="xpath.html#manual.xpath.types"> XPath types</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.select"> Selecting nodes via XPath expression</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.query"> Using query objects</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.variables"> Using variables</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.errors"> Error handling</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.w3c"> Conformance to W3C specification</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="changes.html"> Changelog</a></span></dt>
<dt><span class="section"><a href="apiref.html"> API Reference</a></span></dt>
<dt><span class="section"><a href="toc.html"> Table of Contents</a></span></dt>
</dl></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<a href="xpath.html">XPath</a> |
<a href="apiref.html">API Reference</a> |
<b>Table of Contents</b>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="apiref.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a>
</div></td>
</tr></table>
</body>
</html>

View file

@ -1,749 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>XPath</title>
<link rel="stylesheet" href="../pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../manual.html" title="pugixml 1.6">
<link rel="up" href="../manual.html" title="pugixml 1.6">
<link rel="prev" href="saving.html" title="Saving document">
<link rel="next" href="changes.html" title="Changelog">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<b>XPath</b> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="saving.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="changes.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
<hr>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="manual.xpath"></a><a class="link" href="xpath.html" title="XPath"> XPath</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="xpath.html#manual.xpath.types"> XPath types</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.select"> Selecting nodes via XPath expression</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.query"> Using query objects</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.variables"> Using variables</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.errors"> Error handling</a></span></dt>
<dt><span class="section"><a href="xpath.html#manual.xpath.w3c"> Conformance to W3C specification</a></span></dt>
</dl></div>
<p>
If the task at hand is to select a subset of document nodes that match some
criteria, it is possible to code a function using the existing traversal functionality
for any practical criteria. However, often either a data-driven approach is
desirable, in case the criteria are not predefined and come from a file, or
it is inconvenient to use traversal interfaces and a higher-level DSL is required.
There is a standard language for XML processing, XPath, that can be useful
for these cases. pugixml implements an almost complete subset of XPath 1.0.
Because of differences in document object model and some performance implications,
there are minor violations of the official specifications, which can be found
in <a class="xref" href="xpath.html#manual.xpath.w3c" title="Conformance to W3C specification"> Conformance to W3C specification</a>. The rest of this section describes the interface for XPath
functionality. Please note that if you wish to learn to use XPath language,
you have to look for other tutorials or manuals; for example, you can read
<a href="http://www.w3schools.com/xpath/" target="_top">W3Schools XPath tutorial</a>,
<a href="http://www.tizag.com/xmlTutorial/xpathtutorial.php" target="_top">XPath tutorial
at tizag.com</a>, and <a href="http://www.w3.org/TR/xpath/" target="_top">the XPath
1.0 specification</a>.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.types"></a><a class="link" href="xpath.html#manual.xpath.types" title="XPath types"> XPath types</a>
</h3></div></div></div>
<a name="xpath_value_type"></a><a name="xpath_type_number"></a><a name="xpath_type_string"></a><a name="xpath_type_boolean"></a><a name="xpath_type_node_set"></a><a name="xpath_type_none"></a><p>
Each XPath expression can have one of the following types: boolean, number,
string or node set. Boolean type corresponds to <code class="computeroutput"><span class="keyword">bool</span></code>
type, number type corresponds to <code class="computeroutput"><span class="keyword">double</span></code>
type, string type corresponds to either <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span></code>, depending on whether <a class="link" href="dom.html#manual.dom.unicode" title="Unicode interface">wide
character interface is enabled</a>, and node set corresponds to <a class="link" href="xpath.html#xpath_node_set">xpath_node_set</a> type. There is an enumeration,
<code class="computeroutput"><span class="identifier">xpath_value_type</span></code>, which can
take the values <code class="computeroutput"><span class="identifier">xpath_type_boolean</span></code>,
<code class="computeroutput"><span class="identifier">xpath_type_number</span></code>, <code class="computeroutput"><span class="identifier">xpath_type_string</span></code> or <code class="computeroutput"><span class="identifier">xpath_type_node_set</span></code>,
accordingly.
</p>
<a name="xpath_node"></a><a name="xpath_node::node"></a><a name="xpath_node::attribute"></a><a name="xpath_node::parent"></a><p>
Because an XPath node can be either a node or an attribute, there is a special
type, <code class="computeroutput"><span class="identifier">xpath_node</span></code>, which is
a discriminated union of these types. A value of this type contains two node
handles, one of <code class="computeroutput"><span class="identifier">xml_node</span></code>
type, and another one of <code class="computeroutput"><span class="identifier">xml_attribute</span></code>
type; at most one of them can be non-null. The accessors to get these handles
are available:
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xpath_node</span><span class="special">::</span><span class="identifier">node</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xml_attribute</span> <span class="identifier">xpath_node</span><span class="special">::</span><span class="identifier">attribute</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
XPath nodes can be null, in which case both accessors return null handles.
</p>
<p>
Note that as per XPath specification, each XPath node has a parent, which
can be retrieved via this function:
</p>
<pre class="programlisting"><span class="identifier">xml_node</span> <span class="identifier">xpath_node</span><span class="special">::</span><span class="identifier">parent</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">parent</span></code> function returns the
node's parent if the XPath node corresponds to <code class="computeroutput"><span class="identifier">xml_node</span></code>
handle (equivalent to <code class="computeroutput"><span class="identifier">node</span><span class="special">().</span><span class="identifier">parent</span><span class="special">()</span></code>), or the node to which the attribute belongs
to, if the XPath node corresponds to <code class="computeroutput"><span class="identifier">xml_attribute</span></code>
handle. For null nodes, <code class="computeroutput"><span class="identifier">parent</span></code>
returns null handle.
</p>
<a name="xpath_node::unspecified_bool_type"></a><a name="xpath_node::comparison"></a><p>
Like node and attribute handles, XPath node handles can be implicitly cast
to boolean-like object to check if it is a null node, and also can be compared
for equality with each other.
</p>
<a name="xpath_node::ctor"></a><p>
You can also create XPath nodes with one of the three constructors: the default
constructor, the constructor that takes node argument, and the constructor
that takes attribute and node arguments (in which case the attribute must
belong to the attribute list of the node). The constructor from <code class="computeroutput"><span class="identifier">xml_node</span></code> is implicit, so you can usually
pass <code class="computeroutput"><span class="identifier">xml_node</span></code> to functions
that expect <code class="computeroutput"><span class="identifier">xpath_node</span></code>. Apart
from that you usually don't need to create your own XPath node objects, since
they are returned to you via selection functions.
</p>
<a name="xpath_node_set"></a><p>
XPath expressions operate not on single nodes, but instead on node sets.
A node set is a collection of nodes, which can be optionally ordered in either
a forward document order or a reverse one. Document order is defined in XPath
specification; an XPath node is before another node in document order if
it appears before it in XML representation of the corresponding document.
</p>
<a name="xpath_node_set::const_iterator"></a><a name="xpath_node_set::begin"></a><a name="xpath_node_set::end"></a><p>
Node sets are represented by <code class="computeroutput"><span class="identifier">xpath_node_set</span></code>
object, which has an interface that resembles one of sequential random-access
containers. It has an iterator type along with usual begin/past-the-end iterator
accessors:
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">*</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">const_iterator</span><span class="special">;</span>
<span class="identifier">const_iterator</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">const_iterator</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<a name="xpath_node_set::index"></a><a name="xpath_node_set::size"></a><a name="xpath_node_set::empty"></a><p>
And it also can be iterated via indices, just like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&amp;</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="keyword">operator</span><span class="special">[](</span><span class="identifier">size_t</span> <span class="identifier">index</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">size_t</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">empty</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
All of the above operations have the same semantics as that of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>:
the iterators are random-access, all of the above operations are constant
time, and accessing the element at index that is greater or equal than the
set size results in undefined behavior. You can use both iterator-based and
index-based access for iteration, however the iterator-based one can be faster.
</p>
<a name="xpath_node_set::type"></a><a name="xpath_node_set::type_unsorted"></a><a name="xpath_node_set::type_sorted"></a><a name="xpath_node_set::type_sorted_reverse"></a><a name="xpath_node_set::sort"></a><p>
The order of iteration depends on the order of nodes inside the set; the
order can be queried via the following function:
</p>
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">type_t</span> <span class="special">{</span><span class="identifier">type_unsorted</span><span class="special">,</span> <span class="identifier">type_sorted</span><span class="special">,</span> <span class="identifier">type_sorted_reverse</span><span class="special">};</span>
<span class="identifier">type_t</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">type</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">type</span></code> function returns the
current order of nodes; <code class="computeroutput"><span class="identifier">type_sorted</span></code>
means that the nodes are in forward document order, <code class="computeroutput"><span class="identifier">type_sorted_reverse</span></code>
means that the nodes are in reverse document order, and <code class="computeroutput"><span class="identifier">type_unsorted</span></code>
means that neither order is guaranteed (nodes can accidentally be in a sorted
order even if <code class="computeroutput"><span class="identifier">type</span><span class="special">()</span></code>
returns <code class="computeroutput"><span class="identifier">type_unsorted</span></code>). If
you require a specific order of iteration, you can change it via <code class="computeroutput"><span class="identifier">sort</span></code> function:
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">sort</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">reverse</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">);</span>
</pre>
<p>
Calling <code class="computeroutput"><span class="identifier">sort</span></code> sorts the nodes
in either forward or reverse document order, depending on the argument; after
this call <code class="computeroutput"><span class="identifier">type</span><span class="special">()</span></code>
will return <code class="computeroutput"><span class="identifier">type_sorted</span></code> or
<code class="computeroutput"><span class="identifier">type_sorted_reverse</span></code>.
</p>
<a name="xpath_node_set::first"></a><p>
Often the actual iteration is not needed; instead, only the first element
in document order is required. For this, a special accessor is provided:
</p>
<pre class="programlisting"><span class="identifier">xpath_node</span> <span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">first</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
This function returns the first node in forward document order from the set,
or null node if the set is empty. Note that while the result of the node
does not depend on the order of nodes in the set (i.e. on the result of
<code class="computeroutput"><span class="identifier">type</span><span class="special">()</span></code>),
the complexity does - if the set is sorted, the complexity is constant, otherwise
it is linear in the number of elements or worse.
</p>
<a name="xpath_node_set::ctor"></a><p>
While in the majority of cases the node set is returned by XPath functions,
sometimes there is a need to manually construct a node set. For such cases,
a constructor is provided which takes an iterator range (<code class="computeroutput"><span class="identifier">const_iterator</span></code>
is a typedef for <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">*</span></code>), and an optional type:
</p>
<pre class="programlisting"><span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">xpath_node_set</span><span class="special">(</span><span class="identifier">const_iterator</span> <span class="identifier">begin</span><span class="special">,</span> <span class="identifier">const_iterator</span> <span class="identifier">end</span><span class="special">,</span> <span class="identifier">type_t</span> <span class="identifier">type</span> <span class="special">=</span> <span class="identifier">type_unsorted</span><span class="special">);</span>
</pre>
<p>
The constructor copies the specified range and sets the specified type. The
objects in the range are not checked in any way; you'll have to ensure that
the range contains no duplicates, and that the objects are sorted according
to the <code class="computeroutput"><span class="identifier">type</span></code> parameter. Otherwise
XPath operations with this set may produce unexpected results.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.select"></a><a class="link" href="xpath.html#manual.xpath.select" title="Selecting nodes via XPath expression"> Selecting nodes via XPath expression</a>
</h3></div></div></div>
<a name="xml_node::select_node"></a><a name="xml_node::select_nodes"></a><p>
If you want to select nodes that match some XPath expression, you can do
it with the following functions:
</p>
<pre class="programlisting"><span class="identifier">xpath_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_node</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node_set</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">select_nodes</span></code> function compiles
the expression and then executes it with the node as a context node, and
returns the resulting node set. <code class="computeroutput"><span class="identifier">select_node</span></code>
returns only the first node in document order from the result, and is equivalent
to calling <code class="computeroutput"><span class="identifier">select_nodes</span><span class="special">(</span><span class="identifier">query</span><span class="special">).</span><span class="identifier">first</span><span class="special">()</span></code>.
If the XPath expression does not match anything, or the node handle is null,
<code class="computeroutput"><span class="identifier">select_nodes</span></code> returns an empty
set, and <code class="computeroutput"><span class="identifier">select_node</span></code> returns
null XPath node.
</p>
<p>
If exception handling is not disabled, both functions throw <a class="link" href="xpath.html#xpath_exception">xpath_exception</a>
if the query can not be compiled or if it returns a value with type other
than node set; see <a class="xref" href="xpath.html#manual.xpath.errors" title="Error handling"> Error handling</a> for details.
</p>
<a name="xml_node::select_node_precomp"></a><a name="xml_node::select_nodes_precomp"></a><p>
While compiling expressions is fast, the compilation time can introduce a
significant overhead if the same expression is used many times on small subtrees.
If you're doing many similar queries, consider compiling them into query
objects (see <a class="xref" href="xpath.html#manual.xpath.query" title="Using query objects"> Using query objects</a> for further reference). Once you get a compiled
query object, you can pass it to select functions instead of an expression
string:
</p>
<pre class="programlisting"><span class="identifier">xpath_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_node</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_query</span><span class="special">&amp;</span> <span class="identifier">query</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node_set</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_query</span><span class="special">&amp;</span> <span class="identifier">query</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
If exception handling is not disabled, both functions throw <a class="link" href="xpath.html#xpath_exception">xpath_exception</a>
if the query returns a value with type other than node set.
</p>
<p>
This is an example of selecting nodes using XPath expressions (<a href="../samples/xpath_select.cpp" target="_top">samples/xpath_select.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tools:\n"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span> <span class="special">++</span><span class="identifier">it</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node</span> <span class="identifier">node</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node</span> <span class="identifier">build_tool</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_node</span><span class="special">(</span><span class="string">"//Tool[contains(Description, 'build system')]"</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">build_tool</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Build tool: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">build_tool</span><span class="special">.</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.query"></a><a class="link" href="xpath.html#manual.xpath.query" title="Using query objects"> Using query objects</a>
</h3></div></div></div>
<a name="xpath_query"></a><p>
When you call <code class="computeroutput"><span class="identifier">select_nodes</span></code>
with an expression string as an argument, a query object is created behind
the scenes. A query object represents a compiled XPath expression. Query
objects can be needed in the following circumstances:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
You can precompile expressions to query objects to save compilation time
if it becomes an issue;
</li>
<li class="listitem">
You can use query objects to evaluate XPath expressions which result
in booleans, numbers or strings;
</li>
<li class="listitem">
You can get the type of expression value via query object.
</li>
</ul></div>
<p>
Query objects correspond to <code class="computeroutput"><span class="identifier">xpath_query</span></code>
type. They are immutable and non-copyable: they are bound to the expression
at creation time and can not be cloned. If you want to put query objects
in a container, allocate them on heap via <code class="computeroutput"><span class="keyword">new</span></code>
operator and store pointers to <code class="computeroutput"><span class="identifier">xpath_query</span></code>
in the container.
</p>
<a name="xpath_query::ctor"></a><p>
You can create a query object with the constructor that takes XPath expression
as an argument:
</p>
<pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">xpath_query</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
</pre>
<a name="xpath_query::return_type"></a><p>
The expression is compiled and the compiled representation is stored in the
new query object. If compilation fails, <a class="link" href="xpath.html#xpath_exception">xpath_exception</a>
is thrown if exception handling is not disabled (see <a class="xref" href="xpath.html#manual.xpath.errors" title="Error handling"> Error handling</a> for
details). After the query is created, you can query the type of the evaluation
result using the following function:
</p>
<pre class="programlisting"><span class="identifier">xpath_value_type</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">return_type</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<a name="xpath_query::evaluate_boolean"></a><a name="xpath_query::evaluate_number"></a><a name="xpath_query::evaluate_string"></a><a name="xpath_query::evaluate_node_set"></a><a name="xpath_query::evaluate_node"></a><p>
You can evaluate the query using one of the following functions:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_boolean</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_number</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">string_t</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_string</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node_set</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_node</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
All functions take the context node as an argument, compute the expression
and return the result, converted to the requested type. According to XPath
specification, value of any type can be converted to boolean, number or string
value, but no type other than node set can be converted to node set. Because
of this, <code class="computeroutput"><span class="identifier">evaluate_boolean</span></code>,
<code class="computeroutput"><span class="identifier">evaluate_number</span></code> and <code class="computeroutput"><span class="identifier">evaluate_string</span></code> always return a result,
but <code class="computeroutput"><span class="identifier">evaluate_node_set</span></code> and
<code class="computeroutput"><span class="identifier">evaluate_node</span></code> result in an
error if the return type is not node set (see <a class="xref" href="xpath.html#manual.xpath.errors" title="Error handling"> Error handling</a>).
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Calling <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"query"</span><span class="special">)</span></code>
is equivalent to calling <code class="computeroutput"><span class="identifier">xpath_query</span><span class="special">(</span><span class="string">"query"</span><span class="special">).</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="identifier">node</span><span class="special">)</span></code>. Calling <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">select_node</span><span class="special">(</span><span class="string">"query"</span><span class="special">)</span></code> is equivalent to calling <code class="computeroutput"><span class="identifier">xpath_query</span><span class="special">(</span><span class="string">"query"</span><span class="special">).</span><span class="identifier">evaluate_node</span><span class="special">(</span><span class="identifier">node</span><span class="special">)</span></code>.
</p></td></tr>
</table></div>
<a name="xpath_query::evaluate_string_buffer"></a><p>
Note that <code class="computeroutput"><span class="identifier">evaluate_string</span></code>
function returns the STL string; as such, it's not available in <a class="link" href="install.html#PUGIXML_NO_STL">PUGIXML_NO_STL</a>
mode and also usually allocates memory. There is another string evaluation
function:
</p>
<pre class="programlisting"><span class="identifier">size_t</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">evaluate_string</span><span class="special">(</span><span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">capacity</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
This function evaluates the string, and then writes the result to <code class="computeroutput"><span class="identifier">buffer</span></code> (but at most <code class="computeroutput"><span class="identifier">capacity</span></code>
characters); then it returns the full size of the result in characters, including
the terminating zero. If <code class="computeroutput"><span class="identifier">capacity</span></code>
is not 0, the resulting buffer is always zero-terminated. You can use this
function as follows:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
First call the function with <code class="computeroutput"><span class="identifier">buffer</span>
<span class="special">=</span> <span class="number">0</span></code>
and <code class="computeroutput"><span class="identifier">capacity</span> <span class="special">=</span>
<span class="number">0</span></code>; then allocate the returned amount
of characters, and call the function again, passing the allocated storage
and the amount of characters;
</li>
<li class="listitem">
First call the function with small buffer and buffer capacity; then,
if the result is larger than the capacity, the output has been trimmed,
so allocate a larger buffer and call the function again.
</li>
</ul></div>
<p>
This is an example of using query objects (<a href="../samples/xpath_query.cpp" target="_top">samples/xpath_query.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Select nodes via compiled query
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_remote_tools</span><span class="special">(</span><span class="string">"/Profile/Tools/Tool[@AllowRemote='true']"</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools</span> <span class="special">=</span> <span class="identifier">query_remote_tools</span><span class="special">.</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="identifier">doc</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Remote tool: "</span><span class="special">;</span>
<span class="identifier">tools</span><span class="special">[</span><span class="number">2</span><span class="special">].</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="comment">// Evaluate numbers via compiled query
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_timeouts</span><span class="special">(</span><span class="string">"sum(//Tool/@Timeout)"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">query_timeouts</span><span class="special">.</span><span class="identifier">evaluate_number</span><span class="special">(</span><span class="identifier">doc</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// Evaluate strings via compiled query for different context nodes
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_name_valid</span><span class="special">(</span><span class="string">"string-length(substring-before(@Filename, '_')) &gt; 0 and @OutputFileMasks"</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_name</span><span class="special">(</span><span class="string">"concat(substring-before(@Filename, '_'), ' produces ', @OutputFileMasks)"</span><span class="special">);</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">first_element_by_path</span><span class="special">(</span><span class="string">"Profile/Tools/Tool"</span><span class="special">);</span> <span class="identifier">tool</span><span class="special">;</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">query_name</span><span class="special">.</span><span class="identifier">evaluate_string</span><span class="special">(</span><span class="identifier">tool</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">query_name_valid</span><span class="special">.</span><span class="identifier">evaluate_boolean</span><span class="special">(</span><span class="identifier">tool</span><span class="special">))</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.variables"></a><a class="link" href="xpath.html#manual.xpath.variables" title="Using variables"> Using variables</a>
</h3></div></div></div>
<p>
XPath queries may contain references to variables; this is useful if you
want to use queries that depend on some dynamic parameter without manually
preparing the complete query string, or if you want to reuse the same query
object for similar queries.
</p>
<p>
Variable references have the form <code class="computeroutput"><span class="identifier">$name</span></code>; in order to use them, you have to provide
a variable set, which includes all variables present in the query with correct
types. This set is passed to <code class="computeroutput"><span class="identifier">xpath_query</span></code>
constructor or to <code class="computeroutput"><span class="identifier">select_nodes</span></code>/<code class="computeroutput"><span class="identifier">select_node</span></code> functions:
</p>
<pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">xpath_query</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
<span class="identifier">xpath_node</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_node</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_node_set</span> <span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">query</span><span class="special">,</span> <span class="identifier">xpath_variable_set</span><span class="special">*</span> <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
If you're using query objects, you can change the variable values before
<code class="computeroutput"><span class="identifier">evaluate</span></code>/<code class="computeroutput"><span class="identifier">select</span></code>
calls to change the query behavior.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The variable set pointer is stored in the query object; you have to ensure
that the lifetime of the set exceeds that of query object.
</p></td></tr>
</table></div>
<a name="xpath_variable_set"></a><p>
Variable sets correspond to <code class="computeroutput"><span class="identifier">xpath_variable_set</span></code>
type, which is essentially a variable container.
</p>
<a name="xpath_variable_set::add"></a><p>
You can add new variables with the following function:
</p>
<pre class="programlisting"><span class="identifier">xpath_variable</span><span class="special">*</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">add</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="identifier">xpath_value_type</span> <span class="identifier">type</span><span class="special">);</span>
</pre>
<p>
The function tries to add a new variable with the specified name and type;
if the variable with such name does not exist in the set, the function adds
a new variable and returns the variable handle; if there is already a variable
with the specified name, the function returns the variable handle if variable
has the specified type. Otherwise the function returns null pointer; it also
returns null pointer on allocation failure.
</p>
<p>
New variables are assigned the default value which depends on the type:
<code class="computeroutput"><span class="number">0</span></code> for numbers, <code class="computeroutput"><span class="keyword">false</span></code> for booleans, empty string for strings
and empty set for node sets.
</p>
<a name="xpath_variable_set::get"></a><p>
You can get the existing variables with the following functions:
</p>
<pre class="programlisting"><span class="identifier">xpath_variable</span><span class="special">*</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">);</span>
<span class="keyword">const</span> <span class="identifier">xpath_variable</span><span class="special">*</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">get</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
The functions return the variable handle, or null pointer if the variable
with the specified name is not found.
</p>
<a name="xpath_variable_set::set"></a><p>
Additionally, there are the helper functions for setting the variable value
by name; they try to add the variable with the corresponding type, if it
does not exist, and to set the value. If the variable with the same name
but with different type is already present, they return <code class="computeroutput"><span class="keyword">false</span></code>;
they also return <code class="computeroutput"><span class="keyword">false</span></code> on allocation
failure. Note that these functions do not perform any type conversions.
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable_set</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xpath_node_set</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">);</span>
</pre>
<p>
The variable values are copied to the internal variable storage, so you can
modify or destroy them after the functions return.
</p>
<a name="xpath_variable"></a><p>
If setting variables by name is not efficient enough, or if you have to inspect
variable information or get variable values, you can use variable handles.
A variable corresponds to the <code class="computeroutput"><span class="identifier">xpath_variable</span></code>
type, and a variable handle is simply a pointer to <code class="computeroutput"><span class="identifier">xpath_variable</span></code>.
</p>
<a name="xpath_variable::type"></a><a name="xpath_variable::name"></a><p>
In order to get variable information, you can use one of the following functions:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">xpath_value_type</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">type</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
Note that each variable has a distinct type which is specified upon variable
creation and can not be changed later.
</p>
<a name="xpath_variable::get_boolean"></a><a name="xpath_variable::get_number"></a><a name="xpath_variable::get_string"></a><a name="xpath_variable::get_node_set"></a><p>
In order to get variable value, you should use one of the following functions,
depending on the variable type:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">get_boolean</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">get_number</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">get_string</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">xpath_node_set</span><span class="special">&amp;</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">get_node_set</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
These functions return the value of the variable. Note that no type conversions
are performed; if the type mismatch occurs, a dummy value is returned (<code class="computeroutput"><span class="keyword">false</span></code> for booleans, <code class="computeroutput"><span class="identifier">NaN</span></code>
for numbers, empty string for strings and empty set for node sets).
</p>
<a name="xpath_variable::set"></a><p>
In order to set variable value, you should use one of the following functions,
depending on the variable type:
</p>
<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> <span class="identifier">value</span><span class="special">);</span>
<span class="keyword">bool</span> <span class="identifier">xpath_variable</span><span class="special">::</span><span class="identifier">set</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node_set</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">);</span>
</pre>
<p>
These functions modify the variable value. Note that no type conversions
are performed; if the type mismatch occurs, the functions return <code class="computeroutput"><span class="keyword">false</span></code>; they also return <code class="computeroutput"><span class="keyword">false</span></code>
on allocation failure. The variable values are copied to the internal variable
storage, so you can modify or destroy them after the functions return.
</p>
<p>
This is an example of using variables in XPath queries (<a href="../samples/xpath_variables.cpp" target="_top">samples/xpath_variables.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Select nodes via compiled query
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_variable_set</span> <span class="identifier">vars</span><span class="special">;</span>
<span class="identifier">vars</span><span class="special">.</span><span class="identifier">add</span><span class="special">(</span><span class="string">"remote"</span><span class="special">,</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_type_boolean</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_query</span> <span class="identifier">query_remote_tools</span><span class="special">(</span><span class="string">"/Profile/Tools/Tool[@AllowRemote = string($remote)]"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">vars</span><span class="special">);</span>
<span class="identifier">vars</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">"remote"</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools_remote</span> <span class="special">=</span> <span class="identifier">query_remote_tools</span><span class="special">.</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="identifier">doc</span><span class="special">);</span>
<span class="identifier">vars</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">"remote"</span><span class="special">,</span> <span class="keyword">false</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools_local</span> <span class="special">=</span> <span class="identifier">query_remote_tools</span><span class="special">.</span><span class="identifier">evaluate_node_set</span><span class="special">(</span><span class="identifier">doc</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Remote tool: "</span><span class="special">;</span>
<span class="identifier">tools_remote</span><span class="special">[</span><span class="number">2</span><span class="special">].</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Local tool: "</span><span class="special">;</span>
<span class="identifier">tools_local</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
<span class="comment">// You can pass the context directly to select_nodes/select_node
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools_local_imm</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"/Profile/Tools/Tool[@AllowRemote = string($remote)]"</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">vars</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Local tool imm: "</span><span class="special">;</span>
<span class="identifier">tools_local_imm</span><span class="special">[</span><span class="number">0</span><span class="special">].</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.errors"></a><a class="link" href="xpath.html#manual.xpath.errors" title="Error handling"> Error handling</a>
</h3></div></div></div>
<p>
There are two different mechanisms for error handling in XPath implementation;
the mechanism used depends on whether exception support is disabled (this
is controlled with <a class="link" href="install.html#PUGIXML_NO_EXCEPTIONS">PUGIXML_NO_EXCEPTIONS</a>
define).
</p>
<a name="xpath_exception"></a><a name="xpath_exception::result"></a><a name="xpath_exception::what"></a><p>
By default, XPath functions throw <code class="computeroutput"><span class="identifier">xpath_exception</span></code>
object in case of errors; additionally, in the event any memory allocation
fails, an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bad_alloc</span></code> exception is thrown. Also <code class="computeroutput"><span class="identifier">xpath_exception</span></code> is thrown if the query
is evaluated to a node set, but the return type is not node set. If the query
constructor succeeds (i.e. no exception is thrown), the query object is valid.
Otherwise you can get the error details via one of the following functions:
</p>
<pre class="programlisting"><span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">xpath_exception</span><span class="special">::</span><span class="identifier">what</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">throw</span><span class="special">();</span>
<span class="keyword">const</span> <span class="identifier">xpath_parse_result</span><span class="special">&amp;</span> <span class="identifier">xpath_exception</span><span class="special">::</span><span class="identifier">result</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<a name="xpath_query::unspecified_bool_type"></a><a name="xpath_query::result"></a><p>
If exceptions are disabled, then in the event of parsing failure the query
is initialized to invalid state; you can test if the query object is valid
by using it in a boolean expression: <code class="computeroutput"><span class="keyword">if</span>
<span class="special">(</span><span class="identifier">query</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span>
<span class="special">}</span></code>. Additionally, you can get parsing
result via the result() accessor:
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">xpath_parse_result</span><span class="special">&amp;</span> <span class="identifier">xpath_query</span><span class="special">::</span><span class="identifier">result</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
</pre>
<p>
Without exceptions, evaluating invalid query results in <code class="computeroutput"><span class="keyword">false</span></code>,
empty string, NaN or an empty node set, depending on the type; evaluating
a query as a node set results in an empty node set if the return type is
not node set.
</p>
<a name="xpath_parse_result"></a><p>
The information about parsing result is returned via <code class="computeroutput"><span class="identifier">xpath_parse_result</span></code>
object. It contains parsing status and the offset of last successfully parsed
character from the beginning of the source stream:
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">xpath_parse_result</span>
<span class="special">{</span>
<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">error</span><span class="special">;</span>
<span class="identifier">ptrdiff_t</span> <span class="identifier">offset</span><span class="special">;</span>
<span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">description</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<a name="xpath_parse_result::error"></a><p>
Parsing result is represented as the error message; it is either a null pointer,
in case there is no error, or the error message in the form of ASCII zero-terminated
string.
</p>
<a name="xpath_parse_result::description"></a><p>
<code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code>
member function can be used to get the error message; it never returns the
null pointer, so you can safely use <code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code> even if query parsing succeeded. Note that
<code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code>
returns a <code class="computeroutput"><span class="keyword">char</span></code> string even in
<code class="computeroutput"><span class="identifier">PUGIXML_WCHAR_MODE</span></code>; you'll
have to call <a class="link" href="dom.html#as_wide">as_wide</a> to get the <code class="computeroutput"><span class="keyword">wchar_t</span></code> string.
</p>
<a name="xpath_parse_result::offset"></a><p>
In addition to the error message, parsing result has an <code class="computeroutput"><span class="identifier">offset</span></code>
member, which contains the offset of last successfully parsed character.
This offset is in units of <a class="link" href="dom.html#char_t">pugi::char_t</a> (bytes
for character mode, wide characters for wide character mode).
</p>
<a name="xpath_parse_result::bool"></a><p>
Parsing result object can be implicitly converted to <code class="computeroutput"><span class="keyword">bool</span></code>
like this: <code class="computeroutput"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span>
<span class="keyword">else</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>.
</p>
<p>
This is an example of XPath error handling (<a href="../samples/xpath_error.cpp" target="_top">samples/xpath_error.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Exception is thrown for incorrect query syntax
</span><span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"//nodes[#true()]"</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Select failed: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// Exception is thrown for incorrect query semantics
</span><span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"(123)/next"</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Select failed: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// Exception is thrown for query with incorrect return type
</span><span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"123"</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Select failed: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="manual.xpath.w3c"></a><a class="link" href="xpath.html#manual.xpath.w3c" title="Conformance to W3C specification"> Conformance to W3C specification</a>
</h3></div></div></div>
<p>
Because of the differences in document object models, performance considerations
and implementation complexity, pugixml does not provide a fully conformant
XPath 1.0 implementation. This is the current list of incompatibilities:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Consecutive text nodes sharing the same parent are not merged, i.e. in
<code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;</span><span class="identifier">text1</span>
<span class="special">&lt;![</span><span class="identifier">CDATA</span><span class="special">[</span><span class="identifier">data</span><span class="special">]]&gt;</span> <span class="identifier">text2</span><span class="special">&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span></code> node should have one text node child,
but instead has three.
</li>
<li class="listitem">
Since the document type declaration is not used for parsing, <code class="computeroutput"><span class="identifier">id</span><span class="special">()</span></code>
function always returns an empty node set.
</li>
<li class="listitem">
Namespace nodes are not supported (affects namespace:: axis).
</li>
<li class="listitem">
Name tests are performed on QNames in XML document instead of expanded
names; for <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">foo</span>
<span class="identifier">xmlns</span><span class="special">:</span><span class="identifier">ns1</span><span class="special">=</span><span class="char">'uri'</span> <span class="identifier">xmlns</span><span class="special">:</span><span class="identifier">ns2</span><span class="special">=</span><span class="char">'uri'</span><span class="special">&gt;&lt;</span><span class="identifier">ns1</span><span class="special">:</span><span class="identifier">child</span><span class="special">/&gt;&lt;</span><span class="identifier">ns2</span><span class="special">:</span><span class="identifier">child</span><span class="special">/&gt;&lt;/</span><span class="identifier">foo</span><span class="special">&gt;</span></code>,
query <code class="computeroutput"><span class="identifier">foo</span><span class="special">/</span><span class="identifier">ns1</span><span class="special">:*</span></code>
will return only the first child, not both of them. Compliant XPath implementations
can return both nodes if the user provides appropriate namespace declarations.
</li>
<li class="listitem">
String functions consider a character to be either a single <code class="computeroutput"><span class="keyword">char</span></code> value or a single <code class="computeroutput"><span class="keyword">wchar_t</span></code>
value, depending on the library configuration; this means that some string
functions are not fully Unicode-aware. This affects <code class="computeroutput"><span class="identifier">substring</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">string</span><span class="special">-</span><span class="identifier">length</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">translate</span><span class="special">()</span></code> functions.
</li>
</ul></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2014 Arseny Kapoulkine<p>
Distributed under the MIT License
</p>
</div></td>
</tr></table>
<hr>
<table width="100%"><tr>
<td>
<a href="http://pugixml.org/">pugixml 1.6</a> manual |
<a href="../manual.html">Overview</a> |
<a href="install.html">Installation</a> |
Document:
<a href="dom.html">Object model</a> &middot; <a href="loading.html">Loading</a> &middot; <a href="access.html">Accessing</a> &middot; <a href="modify.html">Modifying</a> &middot; <a href="saving.html">Saving</a> |
<b>XPath</b> |
<a href="apiref.html">API Reference</a> |
<a href="toc.html">Table of Contents</a>
</td>
<td width="*" align="right"><div class="spirit-nav">
<a accesskey="p" href="saving.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../manual.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../manual.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="changes.html"><img src="../images/next.png" alt="Next"></a>
</div></td>
</tr></table>
</body>
</html>

View file

@ -1,880 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>pugixml 1.6</title>
<link rel="stylesheet" href="pugixml.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="quickstart.html" title="pugixml 1.6">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="article">
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="quickstart.main"></a><a class="link" href="quickstart.html#quickstart.main" title="pugixml 1.6 quick start guide"> pugixml 1.6 quick start guide</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="quickstart.html#quickstart.main.introduction"> Introduction</a></span></dt>
<dt><span class="section"><a href="quickstart.html#quickstart.main.install"> Installation</a></span></dt>
<dt><span class="section"><a href="quickstart.html#quickstart.main.dom"> Document object model</a></span></dt>
<dt><span class="section"><a href="quickstart.html#quickstart.main.loading"> Loading document</a></span></dt>
<dt><span class="section"><a href="quickstart.html#quickstart.main.access"> Accessing document data</a></span></dt>
<dt><span class="section"><a href="quickstart.html#quickstart.main.modify"> Modifying document data</a></span></dt>
<dt><span class="section"><a href="quickstart.html#quickstart.main.saving"> Saving document</a></span></dt>
<dt><span class="section"><a href="quickstart.html#quickstart.main.feedback"> Feedback</a></span></dt>
<dt><span class="section"><a href="quickstart.html#quickstart.main.license"> License</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="quickstart.main.introduction"></a><a class="link" href="quickstart.html#quickstart.main.introduction" title="Introduction"> Introduction</a>
</h3></div></div></div>
<p>
<a href="http://pugixml.org/" target="_top">pugixml</a> is a light-weight C++ XML
processing library. It consists of a DOM-like interface with rich traversal/modification
capabilities, an extremely fast XML parser which constructs the DOM tree
from an XML file/buffer, and an XPath 1.0 implementation for complex data-driven
tree queries. Full Unicode support is also available, with Unicode interface
variants and conversions between different Unicode encodings (which happen
automatically during parsing/saving). The library is extremely portable and
easy to integrate and use. pugixml is developed and maintained since 2006
and has many users. All code is distributed under the <a class="link" href="quickstart.html#quickstart.main.license" title="License">MIT
license</a>, making it completely free to use in both open-source and
proprietary applications.
</p>
<p>
pugixml enables very fast, convenient and memory-efficient XML document processing.
However, since pugixml has a DOM parser, it can't process XML documents that
do not fit in memory; also the parser is a non-validating one, so if you
need DTD/Schema validation, the library is not for you.
</p>
<p>
This is the quick start guide for pugixml, which purpose is to enable you
to start using the library quickly. Many important library features are either
not described at all or only mentioned briefly; for more complete information
you <a href="manual.html" target="_top">should read the complete manual</a>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
No documentation is perfect, neither is this one. If you encounter a description
that is unclear, please file an issue as described in <a class="xref" href="quickstart.html#quickstart.main.feedback" title="Feedback"> Feedback</a>. Also if
you can spare the time for a full proof-reading, including spelling and
grammar, that would be great! Please <a class="link" href="quickstart.html#email">send me an e-mail</a>;
as a token of appreciation, your name will be included into the corresponding
section of the manual.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="quickstart.main.install"></a><a class="link" href="quickstart.html#quickstart.main.install" title="Installation"> Installation</a>
</h3></div></div></div>
<p>
pugixml is distributed in source form. You can download a source distribution
via one of the following links:
</p>
<pre class="programlisting"><a href="https://github.com/zeux/pugixml/releases/download/v1.6/pugixml-1.6.zip" target="_top">https://github.com/zeux/pugixml/releases/download/v1.6/pugixml-1.6.zip</a>
<a href="https://github.com/zeux/pugixml/releases/download/v1.6/pugixml-1.6.tar.gz" target="_top">https://github.com/zeux/pugixml/releases/download/v1.6/pugixml-1.6.tar.gz</a>
</pre>
<p>
The distribution contains library source, documentation (the guide you're
reading now and the manual) and some code examples. After downloading the
distribution, install pugixml by extracting all files from the compressed
archive. The files have different line endings depending on the archive format
- <code class="filename">.zip</code> archive has Windows line endings, <code class="filename">.tar.gz</code> archive has Unix line endings.
Otherwise the files in both archives are identical.
</p>
<p>
The complete pugixml source consists of three files - one source file, <code class="filename">pugixml.cpp</code>,
and two header files, <code class="filename">pugixml.hpp</code> and <code class="filename">pugiconfig.hpp</code>. <code class="filename">pugixml.hpp</code> is the primary
header which you need to include in order to use pugixml classes/functions.
The rest of this guide assumes that <code class="filename">pugixml.hpp</code> is either in the current directory
or in one of include directories of your projects, so that <code class="computeroutput"><span class="preprocessor">#include</span> <span class="string">"pugixml.hpp"</span></code>
can find the header; however you can also use relative path (i.e. <code class="computeroutput"><span class="preprocessor">#include</span> <span class="string">"../libs/pugixml/src/pugixml.hpp"</span></code>)
or include directory-relative path (i.e. <code class="computeroutput"><span class="preprocessor">#include</span>
<span class="special">&lt;</span><span class="identifier">xml</span><span class="special">/</span><span class="identifier">thirdparty</span><span class="special">/</span><span class="identifier">pugixml</span><span class="special">/</span><span class="identifier">src</span><span class="special">/</span><span class="identifier">pugixml</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>).
</p>
<p>
The easiest way to build pugixml is to compile the source file, <code class="filename">pugixml.cpp</code>,
along with the existing library/executable. This process depends on the method
of building your application; for example, if you're using Microsoft Visual
Studio<a href="#ftn.trademarks" class="footnote" name="trademarks"><sup class="footnote">[1]</sup></a>,
Apple Xcode, Code::Blocks or any other IDE, just add <code class="filename">pugixml.cpp</code> to one of
your projects. There are other building methods available, including building
pugixml as a standalone static/shared library; <a href="manual/install.html#manual.install.building" target="_top">read
the manual</a> for further information.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="quickstart.main.dom"></a><a class="link" href="quickstart.html#quickstart.main.dom" title="Document object model"> Document object model</a>
</h3></div></div></div>
<p>
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>
<p>
The root of the tree is the document itself, which corresponds to C++ type
<code class="computeroutput"><span class="identifier">xml_document</span></code>. Document has
one or more child nodes, which correspond to C++ type <code class="computeroutput"><span class="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
<code class="computeroutput"><span class="identifier">xml_attribute</span></code>, and some additional
data (i.e. name).
</p>
<p>
The most common node types are:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Document node (<code class="computeroutput"><span class="identifier">node_document</span></code>)
- this is the root of the tree, which consists of several child nodes.
This node corresponds to <code class="computeroutput"><span class="identifier">xml_document</span></code>
class; note that <code class="computeroutput"><span class="identifier">xml_document</span></code>
is a sub-class of <code class="computeroutput"><span class="identifier">xml_node</span></code>,
so the entire node interface is also available.
</li>
<li class="listitem">
Element/tag node (<code class="computeroutput"><span class="identifier">node_element</span></code>)
- 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.
</li>
<li class="listitem">
Plain character data nodes (<code class="computeroutput"><span class="identifier">node_pcdata</span></code>)
represent plain text in XML. PCDATA nodes have a value, but do not have
name or children/attributes. Note that <span class="bold"><strong>plain character
data is not a part of the element node but instead has its own node</strong></span>;
for example, an element node can have several child PCDATA nodes.
</li>
</ul></div>
<p>
Despite the fact that there are several node types, there are only three
C++ types representing the tree (<code class="computeroutput"><span class="identifier">xml_document</span></code>,
<code class="computeroutput"><span class="identifier">xml_node</span></code>, <code class="computeroutput"><span class="identifier">xml_attribute</span></code>);
some operations on <code class="computeroutput"><span class="identifier">xml_node</span></code>
are only valid for certain node types. They are described below.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
All pugixml classes and functions are located in <code class="computeroutput"><span class="identifier">pugi</span></code>
namespace; you have to either use explicit name qualification (i.e. <code class="computeroutput"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span></code>), or to gain access to relevant
symbols via <code class="computeroutput"><span class="keyword">using</span></code> directive
(i.e. <code class="computeroutput"><span class="keyword">using</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span><span class="special">;</span></code> or <code class="computeroutput"><span class="keyword">using</span>
<span class="keyword">namespace</span> <span class="identifier">pugi</span><span class="special">;</span></code>).
</p></td></tr>
</table></div>
<p>
<code class="computeroutput"><span class="identifier">xml_document</span></code> is the owner
of the entire document structure; destroying the document destroys the whole
tree. The interface of <code class="computeroutput"><span class="identifier">xml_document</span></code>
consists of loading functions, saving functions and the entire interface
of <code class="computeroutput"><span class="identifier">xml_node</span></code>, which allows
for document inspection and/or modification. Note that while <code class="computeroutput"><span class="identifier">xml_document</span></code> is a sub-class of <code class="computeroutput"><span class="identifier">xml_node</span></code>, <code class="computeroutput"><span class="identifier">xml_node</span></code>
is not a polymorphic type; the inheritance is present only to simplify usage.
</p>
<p>
<code class="computeroutput"><span class="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. Note that <code class="computeroutput"><span class="identifier">xml_node</span></code> is only a handle to the actual
node, not the node itself - you can have several <code class="computeroutput"><span class="identifier">xml_node</span></code>
handles pointing to the same underlying object. Destroying <code class="computeroutput"><span class="identifier">xml_node</span></code> handle does not destroy the node
and does not remove it from the tree.
</p>
<p>
There is a special value of <code class="computeroutput"><span class="identifier">xml_node</span></code>
type, known as null node or empty node. 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. This is useful
for chaining calls; i.e. you can get the grandparent of a node like so:
<code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">parent</span><span class="special">().</span><span class="identifier">parent</span><span class="special">()</span></code>;
if a node is a null node or it does not have a parent, the first <code class="computeroutput"><span class="identifier">parent</span><span class="special">()</span></code>
call returns null node; the second <code class="computeroutput"><span class="identifier">parent</span><span class="special">()</span></code> call then also returns null node, so you
don't have to check for errors twice. You can test if a handle is null via
implicit boolean cast: <code class="computeroutput"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">node</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>
or <code class="computeroutput"><span class="keyword">if</span> <span class="special">(!</span><span class="identifier">node</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>.
</p>
<p>
<code class="computeroutput"><span class="identifier">xml_attribute</span></code> is the handle
to an XML attribute; it has the same semantics as <code class="computeroutput"><span class="identifier">xml_node</span></code>,
i.e. there can be several <code class="computeroutput"><span class="identifier">xml_attribute</span></code>
handles pointing to the same underlying object and there is a special null
attribute value, which propagates to function results.
</p>
<p>
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 <code class="computeroutput"><span class="identifier">PUGIXML_WCHAR_MODE</span></code> define; you can set
it via <code class="filename">pugiconfig.hpp</code> or via preprocessor options. All tree functions that
work with strings work with either C-style null terminated strings or STL
strings of the selected character type. <a href="manual/dom.html#manual.dom.unicode" target="_top">Read
the manual</a> for additional information on Unicode interface.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="quickstart.main.loading"></a><a class="link" href="quickstart.html#quickstart.main.loading" title="Loading document"> Loading document</a>
</h3></div></div></div>
<p>
pugixml provides several functions for loading XML data from various places
- files, C++ iostreams, memory buffers. All functions use an extremely fast
non-validating parser. This parser is not fully W3C conformant - it can load
any valid XML document, but does not perform some well-formedness checks.
While considerable effort is made to reject invalid XML documents, some validation
is not performed because of performance reasons. XML data is always converted
to internal character format before parsing. pugixml supports all popular
Unicode encodings (UTF-8, UTF-16 (big and little endian), UTF-32 (big and
little endian); UCS-2 is naturally supported since it's a strict subset of
UTF-16) and handles all encoding conversions automatically.
</p>
<p>
The most common source of XML data is files; pugixml provides a separate
function for loading XML document from file. This function accepts file path
as its first argument, and also two optional arguments, which specify parsing
options and input data encoding, which are described in the manual.
</p>
<p>
This is an example of loading XML document from file (<a href="samples/load_file.cpp" target="_top">samples/load_file.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_file</span><span class="special">(</span><span class="string">"tree.xml"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Load result: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">description</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">", mesh name: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"mesh"</span><span class="special">).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"name"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
<code class="computeroutput"><span class="identifier">load_file</span></code>, as well as other
loading functions, destroys the existing document tree and then tries to
load the new tree from the specified file. The result of the operation is
returned in an <code class="computeroutput"><span class="identifier">xml_parse_result</span></code>
object; this object contains the operation status, and the related information
(i.e. last successfully parsed position in the input file, if parsing fails).
</p>
<p>
Parsing result object can be implicitly converted to <code class="computeroutput"><span class="keyword">bool</span></code>;
if you do not want to handle parsing errors thoroughly, you can just check
the return value of load functions as if it was a <code class="computeroutput"><span class="keyword">bool</span></code>:
<code class="computeroutput"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_file</span><span class="special">(</span><span class="string">"file.xml"</span><span class="special">))</span> <span class="special">{</span> <span class="special">...</span>
<span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>.
Otherwise you can use the <code class="computeroutput"><span class="identifier">status</span></code>
member to get parsing status, or the <code class="computeroutput"><span class="identifier">description</span><span class="special">()</span></code> member function to get the status in a
string form.
</p>
<p>
This is an example of handling loading errors (<a href="samples/load_error_handling.cpp" target="_top">samples/load_error_handling.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_document</span> <span class="identifier">doc</span><span class="special">;</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_string</span><span class="special">(</span><span class="identifier">source</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"XML ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">source</span> <span class="special">&lt;&lt;</span> <span class="string">"] parsed without errors, attr value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"node"</span><span class="special">).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"attr"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n\n"</span><span class="special">;</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"XML ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">source</span> <span class="special">&lt;&lt;</span> <span class="string">"] parsed with errors, attr value: ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"node"</span><span class="special">).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"attr"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n"</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Error description: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">description</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Error offset: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">offset</span> <span class="special">&lt;&lt;</span> <span class="string">" (error at [..."</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">source</span> <span class="special">+</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">offset</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"]\n\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
Sometimes XML data should be loaded from some other source than file, i.e.
HTTP URL; also you may want to load XML data from file using non-standard
functions, i.e. to use your virtual file system facilities or to load XML
from gzip-compressed files. These scenarios either require loading document
from memory, in which case you should prepare a contiguous memory block with
all XML data and to pass it to one of buffer loading functions, or loading
document from C++ IOstream, in which case you should provide an object which
implements <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wistream</span></code>
interface.
</p>
<p>
There are different functions for loading document from memory; they treat
the passed buffer as either an immutable one (<code class="computeroutput"><span class="identifier">load_buffer</span></code>),
a mutable buffer which is owned by the caller (<code class="computeroutput"><span class="identifier">load_buffer_inplace</span></code>),
or a mutable buffer which ownership belongs to pugixml (<code class="computeroutput"><span class="identifier">load_buffer_inplace_own</span></code>).
There is also a simple helper function, <code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">load</span></code>,
for cases when you want to load the XML document from null-terminated character
string.
</p>
<p>
This is an example of loading XML document from memory using one of these
functions (<a href="samples/load_memory.cpp" target="_top">samples/load_memory.cpp</a>);
read the sample code for more examples:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">char</span> <span class="identifier">source</span><span class="special">[]</span> <span class="special">=</span> <span class="string">"&lt;mesh name='sphere'&gt;&lt;bounds&gt;0 0 1 1&lt;/bounds&gt;&lt;/mesh&gt;"</span><span class="special">;</span>
<span class="identifier">size_t</span> <span class="identifier">size</span> <span class="special">=</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">source</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// You can use load_buffer_inplace to load document from mutable memory block; the block's lifetime must exceed that of document
</span><span class="keyword">char</span><span class="special">*</span> <span class="identifier">buffer</span> <span class="special">=</span> <span class="keyword">new</span> <span class="keyword">char</span><span class="special">[</span><span class="identifier">size</span><span class="special">];</span>
<span class="identifier">memcpy</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">source</span><span class="special">,</span> <span class="identifier">size</span><span class="special">);</span>
<span class="comment">// The block can be allocated by any method; the block is modified during parsing
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load_buffer_inplace</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">size</span><span class="special">);</span>
<span class="comment">// You have to destroy the block yourself after the document is no longer used
</span><span class="keyword">delete</span><span class="special">[]</span> <span class="identifier">buffer</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
This is a simple example of loading XML document from file using streams
(<a href="samples/load_stream.cpp" target="_top">samples/load_stream.cpp</a>); read
the sample code for more complex examples involving wide streams and locales:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ifstream</span> <span class="identifier">stream</span><span class="special">(</span><span class="string">"weekly-utf-8.xml"</span><span class="special">);</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_parse_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">stream</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="quickstart.main.access"></a><a class="link" href="quickstart.html#quickstart.main.access" title="Accessing document data"> Accessing document data</a>
</h3></div></div></div>
<p>
pugixml features an extensive interface for getting various types of data
from the document and for traversing the document. You can use various accessors
to get node/attribute data, you can traverse the child node/attribute lists
via accessors or iterators, you can do depth-first traversals with <code class="computeroutput"><span class="identifier">xml_tree_walker</span></code> objects, and you can use
XPath for complex data-driven queries.
</p>
<p>
You can get node or attribute name via <code class="computeroutput"><span class="identifier">name</span><span class="special">()</span></code> accessor, and value via <code class="computeroutput"><span class="identifier">value</span><span class="special">()</span></code> accessor. Note that both functions never
return null pointers - they either return a string with the relevant content,
or an empty string if name/value is absent or if the handle is null. Also
there are two notable things for reading values:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
It is common to store data as text contents of some node - i.e. <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">node</span><span class="special">&gt;&lt;</span><span class="identifier">description</span><span class="special">&gt;</span><span class="identifier">This</span>
<span class="identifier">is</span> <span class="identifier">a</span>
<span class="identifier">node</span><span class="special">&lt;/</span><span class="identifier">description</span><span class="special">&gt;&lt;/</span><span class="identifier">node</span><span class="special">&gt;</span></code>.
In this case, <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">description</span><span class="special">&gt;</span></code> node does not have a value, but instead
has a child of type <code class="computeroutput"><span class="identifier">node_pcdata</span></code>
with value <code class="computeroutput"><span class="string">"This is a node"</span></code>.
pugixml provides <code class="computeroutput"><span class="identifier">child_value</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">text</span><span class="special">()</span></code> helper functions to parse such data.
</li>
<li class="listitem">
In many cases attribute values have types that are not strings - i.e.
an attribute may always contain values that should be treated as integers,
despite the fact that they are represented as strings in XML. pugixml
provides several accessors that convert attribute value to some other
type.
</li>
</ul></div>
<p>
This is an example of using these functions (<a href="samples/traverse_base.cpp" target="_top">samples/traverse_base.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">);</span> <span class="identifier">tool</span><span class="special">;</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">))</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">": AllowRemote "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"AllowRemote"</span><span class="special">).</span><span class="identifier">as_bool</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", Timeout "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Timeout"</span><span class="special">).</span><span class="identifier">as_int</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", Description '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">child_value</span><span class="special">(</span><span class="string">"Description"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"'\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
Since a lot of document traversal consists of finding the node/attribute
with the correct name, there are special functions for that purpose. For
example, <code class="computeroutput"><span class="identifier">child</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">)</span></code>
returns the first node which has the name <code class="computeroutput"><span class="string">"Tool"</span></code>,
or null handle if there is no such node. This is an example of using such
functions (<a href="samples/traverse_base.cpp" target="_top">samples/traverse_base.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool for *.dae generation: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">find_child_by_attribute</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">,</span> <span class="string">"OutputFileMasks"</span><span class="special">,</span> <span class="string">"*.dae"</span><span class="special">).</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">);</span> <span class="identifier">tool</span><span class="special">;</span> <span class="identifier">tool</span> <span class="special">=</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">next_sibling</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">))</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool "</span> <span class="special">&lt;&lt;</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
Child node lists and attribute lists are simply double-linked lists; while
you can use <code class="computeroutput"><span class="identifier">previous_sibling</span></code>/<code class="computeroutput"><span class="identifier">next_sibling</span></code> and other such functions for
iteration, pugixml additionally provides node and attribute iterators, so
that you can treat nodes as containers of other nodes or attributes. All
iterators are bidirectional and support all usual iterator operations. The
iterators are invalidated if the node/attribute objects they're pointing
to are removed from the tree; adding nodes/attributes does not invalidate
any iterators.
</p>
<p>
Here is an example of using iterators for document traversal (<a href="samples/traverse_iter.cpp" target="_top">samples/traverse_iter.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span> <span class="special">++</span><span class="identifier">it</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool:"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute_iterator</span> <span class="identifier">ait</span> <span class="special">=</span> <span class="identifier">it</span><span class="special">-&gt;</span><span class="identifier">attributes_begin</span><span class="special">();</span> <span class="identifier">ait</span> <span class="special">!=</span> <span class="identifier">it</span><span class="special">-&gt;</span><span class="identifier">attributes_end</span><span class="special">();</span> <span class="special">++</span><span class="identifier">ait</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span> <span class="special">&lt;&lt;</span> <span class="identifier">ait</span><span class="special">-&gt;</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"="</span> <span class="special">&lt;&lt;</span> <span class="identifier">ait</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">();</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
If your C++ compiler supports range-based for-loop (this is a C++11 feature,
at the time of writing it's supported by Microsoft Visual Studio 11 Beta,
GCC 4.6 and Clang 3.0), you can use it to enumerate nodes/attributes. Additional
helpers are provided to support this; note that they are also compatible
with <a href="http://www.boost.org/libs/foreach/" target="_top">Boost Foreach</a>,
and possibly other pre-C++11 foreach facilities.
</p>
<p>
Here is an example of using C++11 range-based for loop for document traversal
(<a href="samples/traverse_rangefor.cpp" target="_top">samples/traverse_rangefor.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">tool</span><span class="special">:</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">children</span><span class="special">(</span><span class="string">"Tool"</span><span class="special">))</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tool:"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute</span> <span class="identifier">attr</span><span class="special">:</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">attributes</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"="</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">child</span><span class="special">:</span> <span class="identifier">tool</span><span class="special">.</span><span class="identifier">children</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", child "</span> <span class="special">&lt;&lt;</span> <span class="identifier">child</span><span class="special">.</span><span class="identifier">name</span><span class="special">();</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
The methods described above allow traversal of immediate children of some
node; if you want to do a deep tree traversal, you'll have to do it via a
recursive function or some equivalent method. However, pugixml provides a
helper for depth-first traversal of a subtree. In order to use it, you have
to implement <code class="computeroutput"><span class="identifier">xml_tree_walker</span></code>
interface and to call <code class="computeroutput"><span class="identifier">traverse</span></code>
function.
</p>
<p>
This is an example of traversing tree hierarchy with xml_tree_walker (<a href="samples/traverse_walker.cpp" target="_top">samples/traverse_walker.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">simple_walker</span><span class="special">:</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_tree_walker</span>
<span class="special">{</span>
<span class="keyword">virtual</span> <span class="keyword">bool</span> <span class="identifier">for_each</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">node</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="identifier">depth</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span><span class="special">;</span> <span class="comment">// indentation
</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">node_types</span><span class="special">[</span><span class="identifier">node</span><span class="special">.</span><span class="identifier">type</span><span class="special">()]</span> <span class="special">&lt;&lt;</span> <span class="string">": name='"</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"', value='"</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"'\n"</span><span class="special">;</span>
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span> <span class="comment">// continue traversal
</span> <span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">simple_walker</span> <span class="identifier">walker</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">traverse</span><span class="special">(</span><span class="identifier">walker</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
Finally, for complex queries often a higher-level DSL is needed. pugixml
provides an implementation of XPath 1.0 language for such queries. The complete
description of XPath usage can be found in the manual, but here are some
examples:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span> <span class="identifier">tools</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_nodes</span><span class="special">(</span><span class="string">"/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Tools:\n"</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node_set</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">tools</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span> <span class="special">++</span><span class="identifier">it</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node</span> <span class="identifier">node</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xpath_node</span> <span class="identifier">build_tool</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">select_node</span><span class="special">(</span><span class="string">"//Tool[contains(Description, 'build system')]"</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">build_tool</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Build tool: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">build_tool</span><span class="special">.</span><span class="identifier">node</span><span class="special">().</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"Filename"</span><span class="special">).</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
</pre>
<p>
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
XPath functions throw <code class="computeroutput"><span class="identifier">xpath_exception</span></code>
objects on error; the sample above does not catch these exceptions.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="quickstart.main.modify"></a><a class="link" href="quickstart.html#quickstart.main.modify" title="Modifying document data"> Modifying document data</a>
</h3></div></div></div>
<p>
The document in pugixml is fully mutable: you can completely change the document
structure and modify the data of nodes/attributes. All functions take care
of memory management and structural integrity themselves, so they always
result in structurally valid tree - however, it is possible to create an
invalid XML tree (for example, by adding two attributes with the same name
or by setting attribute/node name to empty/invalid string). Tree modification
is optimized for performance and for memory consumption, so if you have enough
memory you can create documents from scratch with pugixml and later save
them to file/stream instead of relying on error-prone manual text writing
and without too much overhead.
</p>
<p>
All member functions that change node/attribute data or structure are non-constant
and thus can not be called on constant handles. However, you can easily convert
constant handle to non-constant one by simple assignment: <code class="computeroutput"><span class="keyword">void</span>
<span class="identifier">foo</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">nc</span> <span class="special">=</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">}</span></code>, so const-correctness
here mainly provides additional documentation.
</p>
<p>
As discussed before, nodes can have name and value, both of which are strings.
Depending on node type, name or value may be absent. You can use <code class="computeroutput"><span class="identifier">set_name</span></code> and <code class="computeroutput"><span class="identifier">set_value</span></code>
member functions to set them. Similar functions are available for attributes;
however, the <code class="computeroutput"><span class="identifier">set_value</span></code> function
is overloaded for some other types except strings, like floating-point numbers.
Also, attribute value can be set using an assignment operator. This is an
example of setting node/attribute name and value (<a href="samples/modify_base.cpp" target="_top">samples/modify_base.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"node"</span><span class="special">);</span>
<span class="comment">// change node name
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">set_name</span><span class="special">(</span><span class="string">"notnode"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", new node name: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// change comment text
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">last_child</span><span class="special">().</span><span class="identifier">set_value</span><span class="special">(</span><span class="string">"useless comment"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", new comment text: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">last_child</span><span class="special">().</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// we can't change value of the element or name of the comment
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span><span class="string">"1"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">last_child</span><span class="special">().</span><span class="identifier">set_name</span><span class="special">(</span><span class="string">"2"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute</span> <span class="identifier">attr</span> <span class="special">=</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"id"</span><span class="special">);</span>
<span class="comment">// change attribute name/value
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">set_name</span><span class="special">(</span><span class="string">"key"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span><span class="string">"345"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">", new attribute: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"="</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// we can use numbers or booleans
</span><span class="identifier">attr</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span><span class="number">1.234</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"new attribute value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="comment">// we can also use assignment operators for more concise code
</span><span class="identifier">attr</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"final attribute value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">attr</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
Nodes and attributes do not exist without a document tree, so you can't create
them without adding them to some document. A node or attribute can be created
at the end of node/attribute list or before/after some other node. All insertion
functions return the handle to newly created object on success, and null
handle on failure. Even if the operation fails (for example, if you're trying
to add a child node to PCDATA node), the document remains in consistent state,
but the requested node/attribute is not added.
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
attribute() and child() functions do not add attributes or nodes to the
tree, so code like <code class="computeroutput"><span class="identifier">node</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"id"</span><span class="special">)</span> <span class="special">=</span> <span class="number">123</span><span class="special">;</span></code> will not do anything if <code class="computeroutput"><span class="identifier">node</span></code> does not have an attribute with
name <code class="computeroutput"><span class="string">"id"</span></code>. Make sure
you're operating with existing attributes/nodes by adding them if necessary.
</p></td></tr>
</table></div>
<p>
This is an example of adding new attributes/nodes to the document (<a href="samples/modify_add.cpp" target="_top">samples/modify_add.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// add node with some name
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">append_child</span><span class="special">(</span><span class="string">"node"</span><span class="special">);</span>
<span class="comment">// add description node with text child
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">descr</span> <span class="special">=</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">append_child</span><span class="special">(</span><span class="string">"description"</span><span class="special">);</span>
<span class="identifier">descr</span><span class="special">.</span><span class="identifier">append_child</span><span class="special">(</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">node_pcdata</span><span class="special">).</span><span class="identifier">set_value</span><span class="special">(</span><span class="string">"Simple node"</span><span class="special">);</span>
<span class="comment">// add param node before the description
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">param</span> <span class="special">=</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">insert_child_before</span><span class="special">(</span><span class="string">"param"</span><span class="special">,</span> <span class="identifier">descr</span><span class="special">);</span>
<span class="comment">// add attributes to param node
</span><span class="identifier">param</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"name"</span><span class="special">)</span> <span class="special">=</span> <span class="string">"version"</span><span class="special">;</span>
<span class="identifier">param</span><span class="special">.</span><span class="identifier">append_attribute</span><span class="special">(</span><span class="string">"value"</span><span class="special">)</span> <span class="special">=</span> <span class="number">1.1</span><span class="special">;</span>
<span class="identifier">param</span><span class="special">.</span><span class="identifier">insert_attribute_after</span><span class="special">(</span><span class="string">"type"</span><span class="special">,</span> <span class="identifier">param</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"name"</span><span class="special">))</span> <span class="special">=</span> <span class="string">"float"</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
If you do not want your document to contain some node or attribute, you can
remove it with <code class="computeroutput"><span class="identifier">remove_attribute</span></code>
and <code class="computeroutput"><span class="identifier">remove_child</span></code> functions.
Removing the attribute or node invalidates all handles to the same underlying
object, and also invalidates all iterators pointing to the same object. Removing
node also invalidates all past-the-end iterators to its attribute or child
node list. Be careful to ensure that all such handles and iterators either
do not exist or are not used after the attribute/node is removed.
</p>
<p>
This is an example of removing attributes/nodes from the document (<a href="samples/modify_remove.cpp" target="_top">samples/modify_remove.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// remove description node with the whole subtree
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">node</span> <span class="special">=</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"node"</span><span class="special">);</span>
<span class="identifier">node</span><span class="special">.</span><span class="identifier">remove_child</span><span class="special">(</span><span class="string">"description"</span><span class="special">);</span>
<span class="comment">// remove id attribute
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_node</span> <span class="identifier">param</span> <span class="special">=</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">child</span><span class="special">(</span><span class="string">"param"</span><span class="special">);</span>
<span class="identifier">param</span><span class="special">.</span><span class="identifier">remove_attribute</span><span class="special">(</span><span class="string">"value"</span><span class="special">);</span>
<span class="comment">// we can also remove nodes/attributes by handles
</span><span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_attribute</span> <span class="identifier">id</span> <span class="special">=</span> <span class="identifier">param</span><span class="special">.</span><span class="identifier">attribute</span><span class="special">(</span><span class="string">"name"</span><span class="special">);</span>
<span class="identifier">param</span><span class="special">.</span><span class="identifier">remove_attribute</span><span class="special">(</span><span class="identifier">id</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="quickstart.main.saving"></a><a class="link" href="quickstart.html#quickstart.main.saving" title="Saving document"> Saving document</a>
</h3></div></div></div>
<p>
Often after creating a new document or loading the existing one and processing
it, it is necessary to save the result back to file. Also it is occasionally
useful to output the whole document or a subtree to some stream; use cases
include debug printing, serialization via network or other text-oriented
medium, etc. pugixml provides several functions to output any subtree of
the document to a file, stream or another generic transport interface; these
functions allow to customize the output format, and also perform necessary
encoding conversions.
</p>
<p>
Before writing to the destination the node/attribute data is properly formatted
according to the node type; all special XML symbols, such as &lt; and &amp;,
are properly escaped. In order to guard against forgotten node/attribute
names, empty node/attribute names are printed as <code class="computeroutput"><span class="string">":anonymous"</span></code>.
For well-formed output, make sure all node and attribute names are set to
meaningful values.
</p>
<p>
If you want to save the whole document to a file, you can use the <code class="computeroutput"><span class="identifier">save_file</span></code> function, which returns <code class="computeroutput"><span class="keyword">true</span></code> on success. This is a simple example
of saving XML document to file (<a href="samples/save_file.cpp" target="_top">samples/save_file.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// save document to file
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Saving result: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">doc</span><span class="special">.</span><span class="identifier">save_file</span><span class="special">(</span><span class="string">"save_file_output.xml"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
To enhance interoperability pugixml provides functions for saving document
to any object which implements C++ <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span></code>
interface. This allows you to save documents to any standard C++ stream (i.e.
file stream) or any third-party compliant implementation (i.e. Boost Iostreams).
Most notably, this allows for easy debug output, since you can use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code>
stream as saving target. There are two functions, one works with narrow character
streams, another handles wide character ones.
</p>
<p>
This is a simple example of saving XML document to standard output (<a href="samples/save_stream.cpp" target="_top">samples/save_stream.cpp</a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// save document to standard output
</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Document:\n"</span><span class="special">;</span>
<span class="identifier">doc</span><span class="special">.</span><span class="identifier">save</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
All of the above saving functions are implemented in terms of writer interface.
This is a simple interface with a single function, which is called several
times during output process with chunks of document data as input. In order
to output the document via some custom transport, for example sockets, you
should create an object which implements <code class="computeroutput"><span class="identifier">xml_writer_file</span></code>
interface and pass it to <code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span></code>
function.
</p>
<p>
This is a simple example of custom writer for saving document data to STL
string (<a href="samples/save_custom_writer.cpp" target="_top">samples/save_custom_writer.cpp</a>);
read the sample code for more complex examples:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">xml_string_writer</span><span class="special">:</span> <span class="identifier">pugi</span><span class="special">::</span><span class="identifier">xml_writer</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span><span class="special">;</span>
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">write</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">result</span><span class="special">.</span><span class="identifier">append</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*&gt;(</span><span class="identifier">data</span><span class="special">),</span> <span class="identifier">size</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
While the previously described functions save the whole document to the destination,
it is easy to save a single subtree. Instead of calling <code class="computeroutput"><span class="identifier">xml_document</span><span class="special">::</span><span class="identifier">save</span></code>,
just call <code class="computeroutput"><span class="identifier">xml_node</span><span class="special">::</span><span class="identifier">print</span></code> function on the target node. You
can save node contents to C++ IOstream object or custom writer in this way.
Saving a subtree slightly differs from saving the whole document; <a href="manual/saving.html#manual.saving.subtree" target="_top">read the manual</a> for
more information.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="quickstart.main.feedback"></a><a class="link" href="quickstart.html#quickstart.main.feedback" title="Feedback"> Feedback</a>
</h3></div></div></div>
<p>
If you believe you've found a bug in pugixml, please file an issue via <a href="https://github.com/zeux/pugixml/issues/new" target="_top">issue submission form</a>.
Be sure to include the relevant information so that the bug can be reproduced:
the version of pugixml, compiler version and target architecture, the code
that uses pugixml and exhibits the bug, etc. Feature requests and contributions
can be filed as issues, too.
</p>
<a name="email"></a><p>
If filing an issue is not possible due to privacy or other concerns, you
can contact pugixml author by e-mail directly: <a href="mailto:arseny.kapoulkine@gmail.com" target="_top">arseny.kapoulkine@gmail.com</a>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="quickstart.main.license"></a><a class="link" href="quickstart.html#quickstart.main.license" title="License"> License</a>
</h3></div></div></div>
<p>
The pugixml library is distributed under the MIT license:
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
Copyright (c) 2006-2014 Arseny Kapoulkine
</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
</p>
</blockquote></div>
<p>
This means that you can freely use pugixml in your applications, both open-source
and proprietary. If you use pugixml in a product, it is sufficient to add
an acknowledgment like this to the product distribution:
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
This software is based on pugixml library (http://pugixml.org).<br>
pugixml
is Copyright (C) 2006-2014 Arseny Kapoulkine.
</p></blockquote></div>
</div>
</div>
<div class="footnotes">
<br><hr style="width:100; text-align:left;margin-left: 0">
<div id="ftn.trademarks" class="footnote"><p><a href="#trademarks" class="para"><sup class="para">[1] </sup></a>All trademarks used are properties of their respective owners.</p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: March 20, 2015 at 07:16:25 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
</body>
</html>