diff options
58 files changed, 2154 insertions, 1446 deletions
diff --git a/Jamfile.jam b/Jamfile.jam index d85188d..512e2c9 100644 --- a/Jamfile.jam +++ b/Jamfile.jam @@ -144,7 +144,7 @@ for SAMPLE in [ Glob docs/samples : *.cpp ] } # release -VERSION = 1.4 ; +VERSION = 1.5 ; RELEASE_FILES = [ Glob contrib : *.cpp *.hpp ] [ Glob src : *.cpp *.hpp ] diff --git a/Jamrules.jam b/Jamrules.jam index ab960c7..c1647cb 100644 --- a/Jamrules.jam +++ b/Jamrules.jam @@ -839,8 +839,8 @@ else if ( $(OS) = NT ) { - QUICKBOOK = %QUICKBOOK_PATH%\bin\quickbook.exe ; - XSLTPROC = %QUICKBOOK_PATH%\bin\xsltproc.exe ; + QUICKBOOK = %QUICKBOOK_PATH%bin\\quickbook.exe ; + XSLTPROC = %QUICKBOOK_PATH%bin\\xsltproc.exe ; } else { @@ -30,7 +30,7 @@ all: $(EXECUTABLE) ifeq ($(config),coverage) test: $(EXECUTABLE) - @find $(BUILD) -name '*.gcda' | xargs -r rm + -@find $(BUILD) -name '*.gcda' | xargs rm ./$(EXECUTABLE) @gcov -b -c $(BUILD)/src/pugixml.cpp.gcda | sed -e '/./{H;$!d;}' -e 'x;/pugixml.cpp/!d;' @ls *.gcov | grep -v pugixml.cpp.gcov | xargs rm @@ -12,8 +12,8 @@ pugixml is used by a lot of projects, both open-source and proprietary, for perf Documentation for the current release of pugixml is available on-line as two separate documents: -* [Quick-start guide](http://cdn.rawgit.com/zeux/pugixml/v1.4/docs/quickstart.html), that aims to provide enough information to start using the library; -* [Complete reference manual](http://cdn.rawgit.com/zeux/pugixml/v1.4/docs/manual.html), that describes all features of the library in detail. +* [Quick-start guide](http://cdn.rawgit.com/zeux/pugixml/v1.5/docs/quickstart.html), that aims to provide enough information to start using the library; +* [Complete reference manual](http://cdn.rawgit.com/zeux/pugixml/v1.5/docs/manual.html), that describes all features of the library in detail. You’re advised to start with the quick-start guide; however, many important library features are either not described in it at all or only mentioned briefly; if you require more information you should read the complete manual. diff --git a/docs/manual.html b/docs/manual.html index ecac884..0eb13b9 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -1,16 +1,16 @@ <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> -<title>pugixml 1.4</title> +<title>pugixml 1.5</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.4"> +<link rel="home" href="manual.html" title="pugixml 1.5"> <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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <b>Overview</b> | <a href="manual/install.html">Installation</a> | Document: @@ -24,17 +24,17 @@ <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> +<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> +<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> +<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 @@ -69,7 +69,7 @@ </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>. + 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 @@ -80,7 +80,7 @@ </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> +<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 @@ -107,14 +107,14 @@ 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> -<p> - <a name="email"></a>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>. +<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> +<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 @@ -140,7 +140,7 @@ </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> +<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: @@ -184,13 +184,13 @@ pugixml </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: February 28, 2014 at 06:00:02 GMT</small></p></td> +<td align="left"><p><small>Last revised: November 26, 2014 at 02:23:21 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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <b>Overview</b> | <a href="manual/install.html">Installation</a> | Document: diff --git a/docs/manual.qbk b/docs/manual.qbk index 833962d..fec889a 100644 --- a/docs/manual.qbk +++ b/docs/manual.qbk @@ -1,7 +1,7 @@ [book pugixml [quickbook 1.5] - [version 1.4] + [version 1.5] [id manual] [copyright 2014 Arseny Kapoulkine] [license Distributed under the MIT License] @@ -30,11 +30,11 @@ This is the complete manual for pugixml, which describes all features of the lib [section:feedback Feedback] -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 [@http://code.google.com/p/pugixml/issues/entry issue submission form]. 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. +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 [@https://github.com/zeux/pugixml/issues/new issue submission form]. 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 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, [@http://code.google.com/p/pugixml/issues/entry?template=Feature%20request file an issue]. 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. +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, [@https://github.com/zeux/pugixml/issues/new file an issue]. 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. -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 [@http://code.google.com/p/pugixml/issues/entry?template=Feature%20request file an issue]. 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. +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 [@https://github.com/zeux/pugixml/issues/new file an issue]. 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. [#email] If filing an issue is not possible due to privacy or other concerns, you can contact pugixml author by e-mail directly: [@mailto:arseny.kapoulkine@gmail.com arseny.kapoulkine@gmail.com]. @@ -99,46 +99,48 @@ pugixml is Copyright (C) 2006-2014 Arseny Kapoulkine. [section:getting Getting pugixml] -pugixml is distributed in source form. You can either download a source distribution or checkout the Subversion repository. +pugixml is distributed in source form. You can either download a source distribution or clone the Git repository. [section:source Source distributions] You can download the latest source distribution via one of the following links: [pre -[@https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.zip] -[@https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.tar.gz] +[@https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.zip] +[@https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.tar.gz] ] 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 - [file .zip] archive has Windows line endings, [file .tar.gz] archive has Unix line endings. Otherwise the files in both archives are identical. -If you need an older version, you can download it from the [@http://code.google.com/p/pugixml/downloads/list version archive]. +If you need an older version, you can download it from the [@https://github.com/zeux/pugixml/releases version archive]. [endsect] [/source] -[section:subversion Subversion repository] +[section:git Git repository] -The Subversion repository is located at [@http://pugixml.googlecode.com/svn/]. There is a Subversion tag "release-{version}" for each version; also there is the "latest" tag, which always points to the latest stable release. +The Git repository is located at [@https://github.com/zeux/pugixml/]. There is a Git tag "v{version}" for each version; also there is the "latest" tag, which always points to the latest stable release. For example, to checkout the current version, you can use this command: -[pre svn checkout http://pugixml.googlecode.com/svn/tags/release-1.4 pugixml] - -To checkout the latest version, you can use this command: - -[pre svn checkout http://pugixml.googlecode.com/svn/tags/latest pugixml] +[pre +git clone https://github.com/zeux/pugixml +cd pugixml +git checkout v1.5 +] The repository contains library source, documentation, code examples and full unit test suite. -Use latest version tag if you want to automatically get new versions via =svn update=. Use other tags if you want to switch to new versions only explicitly (for example, using =svn switch= command). Also please note that Subversion trunk contains the work-in-progress version of the code; while this means that you can get new features and bug fixes from trunk without waiting for a new release, this also means that occasionally the code can be broken in some configurations. +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. -[endsect] [/subversion] +[endsect] [/git] -[section:git Git repository] +[section:subversion Subversion repository] -The Subversion repository is mirrored by a Git repository at [@https://github.com/zeux/pugixml]. The mirror is frequently updated and has the same structure in terms of tags and contents as Subversion repository. +You can access the Git repository via Subversion using [@https://github.com/zeux/pugixml] URL. For example, to checkout the current version, you can use this command: -[endsect] [/git] +[pre svn checkout https://github.com/zeux/pugixml/tags/v1.5 pugixml] + +[endsect] [/subversion] [endsect] [/getting] @@ -600,7 +602,7 @@ The best way from the performance/memory point of view is to load document using [#xml_document::load_string] There is also a simple helper function for cases when you want to load the XML document from null-terminated character string: - xml_parse_result xml_document::load(const char_t* contents, unsigned int options = parse_default); + xml_parse_result xml_document::load_string(const char_t* contents, unsigned int options = parse_default); It is equivalent to calling `load_buffer` with `size` being either `strlen(contents)` or `wcslen(contents) * sizeof(wchar_t)`, 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. @@ -1188,6 +1190,7 @@ In addition to string functions, several functions are provided for handling att bool xml_attribute::set_value(int rhs); bool xml_attribute::set_value(unsigned int rhs); bool xml_attribute::set_value(double rhs); + bool xml_attribute::set_value(float rhs); bool xml_attribute::set_value(bool rhs); bool xml_attribute::set_value(long long rhs); bool xml_attribute::set_value(unsigned long long rhs); @@ -1206,6 +1209,7 @@ For convenience, all `set_value` functions have the corresponding assignment ope xml_attribute& xml_attribute::operator=(int rhs); xml_attribute& xml_attribute::operator=(unsigned int rhs); xml_attribute& xml_attribute::operator=(double rhs); + xml_attribute& xml_attribute::operator=(float rhs); xml_attribute& xml_attribute::operator=(bool rhs); xml_attribute& xml_attribute::operator=(long long rhs); xml_attribute& xml_attribute::operator=(unsigned long long rhs); @@ -1310,6 +1314,7 @@ In addition to a string function, several functions are provided for handling te bool xml_text::set(int rhs); bool xml_text::set(unsigned int rhs); bool xml_text::set(double rhs); + bool xml_text::set(float rhs); bool xml_text::set(bool rhs); bool xml_text::set(long long rhs); bool xml_text::set(unsigned long long rhs); @@ -1324,6 +1329,7 @@ For convenience, all `set` functions have the corresponding assignment operators xml_text& xml_text::operator=(int rhs); xml_text& xml_text::operator=(unsigned int rhs); xml_text& xml_text::operator=(double rhs); + xml_text& xml_text::operator=(float rhs); xml_text& xml_text::operator=(bool rhs); xml_text& xml_text::operator=(long long rhs); xml_text& xml_text::operator=(unsigned long long rhs); @@ -1890,6 +1896,38 @@ Because of the differences in document object models, performance considerations [section:changes Changelog] +[h5 27.11.2014 - version 1.5] + +Major release, featuring a lot of performance improvements and some new features. + +* Specification changes: + # xml_document::load(const char_t*) was renamed to load_string; the old method is still available and will be deprecated in a future release + # xml_node::select_single_node was renamed to select_node; the old method is still available and will be deprecated in a future release. + +* New features: + # Added xml_node::append_move and other functions for moving nodes within a document + # Added xpath_query::evaluate_node for evaluating queries with a single node as a result + +* Performance improvements: + # Optimized XML parsing (10-40% faster with clang/gcc, up to 10% faster with MSVC) + # Optimized memory consumption when copying nodes in the same document (string contents is now shared) + # Optimized node copying (10% faster for cross-document copies, 3x faster for inter-document copies; also it now consumes a constant amount of stack space) + # Optimized node output (60% faster; also it now consumes a constant amount of stack space) + # Optimized XPath allocation (query evaluation now results in fewer temporary allocations) + # Optimized XPath sorting (node set sorting is 2-3x faster in some cases) + # Optimized XPath evaluation (XPathMark suite is 100x faster; some commonly used queries are 3-4x faster) + +* Compatibility improvements: + # Fixed xml_node::offset_debug for corner cases + # Fixed undefined behavior while calling memcpy in some cases + # Fixed MSVC 2015 compilation warnings + # Fixed contrib/foreach.hpp for Boost 1.56.0 + +* Bug fixes + # Adjusted comment output to avoid malformed documents if the comment value contains "--" + # Fix XPath sorting for documents that were constructed using append_buffer + # Fix load_file for wide-character paths with non-ASCII characters in MinGW with C++11 mode enabled + [h5 27.02.2014 - version 1.4] Major release, featuring various new features, bug fixes and compatibility improvements. @@ -2335,6 +2373,7 @@ Classes: * `bool `[link xml_attribute::set_value set_value]`(int rhs);` * `bool `[link xml_attribute::set_value set_value]`(unsigned int rhs);` * `bool `[link xml_attribute::set_value set_value]`(double rhs);` + * `bool `[link xml_attribute::set_value set_value]`(float rhs);` * `bool `[link xml_attribute::set_value set_value]`(bool rhs);` * `bool `[link xml_attribute::set_value set_value]`(long long rhs);` * `bool `[link xml_attribute::set_value set_value]`(unsigned long long rhs);` @@ -2344,6 +2383,7 @@ Classes: * `xml_attribute& `[link xml_attribute::assign operator=]`(int rhs);` * `xml_attribute& `[link xml_attribute::assign operator=]`(unsigned int rhs);` * `xml_attribute& `[link xml_attribute::assign operator=]`(double rhs);` + * `xml_attribute& `[link xml_attribute::assign operator=]`(float rhs);` * `xml_attribute& `[link xml_attribute::assign operator=]`(bool rhs);` * `xml_attribute& `[link xml_attribute::assign operator=]`(long long rhs);` * `xml_attribute& `[link xml_attribute::assign operator=]`(unsnigned long long rhs);` @@ -2501,7 +2541,7 @@ Classes: * `xml_parse_result `[link xml_document::load_stream load]`(std::wistream& stream, unsigned int options = parse_default);` [lbr] - * `xml_parse_result `[link xml_document::load_string load]`(const char_t* contents, unsigned int options = parse_default);` + * `xml_parse_result `[link xml_document::load_string load_string]`(const char_t* contents, unsigned int options = parse_default);` [lbr] * `xml_parse_result `[link xml_document::load_file load_file]`(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);` @@ -2574,6 +2614,7 @@ Classes: * `bool `[link xml_text::set set]`(int rhs);` * `bool `[link xml_text::set set]`(unsigned int rhs);` * `bool `[link xml_text::set set]`(double rhs);` + * `bool `[link xml_text::set set]`(float rhs);` * `bool `[link xml_text::set set]`(bool rhs);` * `bool `[link xml_text::set set]`(long long rhs);` * `bool `[link xml_text::set set]`(unsigned long long rhs);` @@ -2583,6 +2624,7 @@ Classes: * `xml_text& `[link xml_text::assign operator=]`(int rhs);` * `xml_text& `[link xml_text::assign operator=]`(unsigned int rhs);` * `xml_text& `[link xml_text::assign operator=]`(double rhs);` + * `xml_text& `[link xml_text::assign operator=]`(float rhs);` * `xml_text& `[link xml_text::assign operator=]`(bool rhs);` * `xml_text& `[link xml_text::assign operator=]`(long long rhs);` * `xml_text& `[link xml_text::assign operator=]`(unsigned long long rhs);` diff --git a/docs/manual/access.html b/docs/manual/access.html index 4d4e9c2..8942a26 100644 --- a/docs/manual/access.html +++ b/docs/manual/access.html @@ -4,15 +4,15 @@ <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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> <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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: @@ -28,27 +28,27 @@ <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> +<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 +<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 +<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> +<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>, + 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 @@ -58,12 +58,11 @@ </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> +<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> -<p> - <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>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 +<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 @@ -124,6 +123,7 @@ 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> @@ -142,15 +142,15 @@ </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> +<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> -<p> - <a name="xml_node::name"></a><a name="xml_node::value"></a>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 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> @@ -164,9 +164,8 @@ 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> -<p> - <a name="xml_node::child_value"></a>It is common to store data as text contents - of some node - i.e. <code class="computeroutput"><span class="special"><</span><span class="identifier">node</span><span class="special">><</span><span class="identifier">description</span><span class="special">></span><span class="identifier">This</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">node</span><span class="special"></</span><span class="identifier">description</span><span class="special">></</span><span class="identifier">node</span><span class="special">></span></code>. +<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"><</span><span class="identifier">node</span><span class="special">><</span><span class="identifier">description</span><span class="special">></span><span class="identifier">This</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">node</span><span class="special"></</span><span class="identifier">description</span><span class="special">></</span><span class="identifier">node</span><span class="special">></span></code>. In this case, <code class="computeroutput"><span class="special"><</span><span class="identifier">description</span><span class="special">></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 @@ -189,7 +188,7 @@ <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. + <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 @@ -198,12 +197,11 @@ </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> +<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> -<p> - <a name="xml_attribute::name"></a><a name="xml_attribute::value"></a>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>: +<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> @@ -212,12 +210,12 @@ In case the attribute handle is null, both functions return empty strings - they never return null pointers. </p> -<p> - <a name="xml_attribute::as_string"></a>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: +<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> @@ -226,12 +224,11 @@ 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> -<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>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: +<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> @@ -296,11 +293,12 @@ <span class="keyword">long</span></code> type, including string conversions. </p></td></tr> </table></div> -<p> - <a name="code_traverse_base_data"></a>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>): +<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> @@ -315,12 +313,11 @@ </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> +<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> -<p> - <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>Since a lot of document traversal consists - of finding the node/attribute with the correct name, there are special functions - for that purpose: +<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> @@ -342,15 +339,11 @@ </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> -<p> - <a name="xml_node::find_child_by_attribute"></a>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"><</span><span class="identifier">group</span><span class="special">><</span><span class="identifier">item</span> - <span class="identifier">id</span><span class="special">=</span><span class="string">"1"</span><span class="special">/></span> - <span class="special"><</span><span class="identifier">item</span> - <span class="identifier">id</span><span class="special">=</span><span class="string">"2"</span><span class="special">/></</span><span class="identifier">group</span><span class="special">></span></code>. - There are two functions for finding child nodes based on the attribute values: +<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"><</span><span class="identifier">group</span><span class="special">><</span><span class="identifier">item</span> <span class="identifier">id</span><span class="special">=</span><span class="string">"1"</span><span class="special">/></span> <span class="special"><</span><span class="identifier">item</span> <span class="identifier">id</span><span class="special">=</span><span class="string">"2"</span><span class="special">/></</span><span class="identifier">group</span><span class="special">></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> @@ -370,6 +363,7 @@ 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"><<</span> <span class="string">"Tool for *.dae generation: "</span> <span class="special"><<</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"><<</span> <span class="string">"\n"</span><span class="special">;</span> @@ -383,13 +377,12 @@ </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> +<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> -<p> - <a name="xml_node::children"></a><a name="xml_node::attributes"></a>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 +<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. @@ -410,6 +403,7 @@ 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> @@ -433,12 +427,12 @@ </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 +<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> -<p> - <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>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 +<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> @@ -486,6 +480,7 @@ 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> @@ -518,14 +513,14 @@ </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> +<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> -<p> - <a name="xml_tree_walker"></a>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> +<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> @@ -541,9 +536,8 @@ <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">&</span> <span class="identifier">walker</span><span class="special">);</span> </pre> -<p> - <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>The traversal - is launched by calling <code class="computeroutput"><span class="identifier">traverse</span></code> +<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; "> @@ -570,10 +564,10 @@ <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> -<p> - <a name="xml_tree_walker::depth"></a>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> +<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 @@ -583,22 +577,24 @@ 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">&</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"><</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"><<</span> <span class="string">" "</span><span class="special">;</span> <span class="comment">// indentation</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"><</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"><<</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"><<</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"><<</span> <span class="string">": name='"</span> <span class="special"><<</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"', value='"</span> <span class="special"><<</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special"><<</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="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> @@ -608,15 +604,15 @@ </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 +<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> -<p> - <a name="xml_node::find_attribute"></a><a name="xml_node::find_child"></a><a name="xml_node::find_node"></a>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: +<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"><</span><span class="keyword">typename</span> <span class="identifier">Predicate</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">Predicate</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</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> @@ -658,6 +654,7 @@ 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> @@ -680,29 +677,29 @@ <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"><<</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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +<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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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> +<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> -<p> - <a name="xml_text"></a>It is common to store data as text contents of some - node - i.e. <code class="computeroutput"><span class="special"><</span><span class="identifier">node</span><span class="special">><</span><span class="identifier">description</span><span class="special">></span><span class="identifier">This</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">node</span><span class="special"></</span><span class="identifier">description</span><span class="special">></</span><span class="identifier">node</span><span class="special">></span></code>. +<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"><</span><span class="identifier">node</span><span class="special">><</span><span class="identifier">description</span><span class="special">></span><span class="identifier">This</span> <span class="identifier">is</span> <span class="identifier">a</span> <span class="identifier">node</span><span class="special"></</span><span class="identifier">description</span><span class="special">></</span><span class="identifier">node</span><span class="special">></span></code>. In this case, <code class="computeroutput"><span class="special"><</span><span class="identifier">description</span><span class="special">></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 @@ -711,10 +708,8 @@ 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> -<p> - <a name="xml_node::text"></a>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: +<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> @@ -724,11 +719,11 @@ 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> -<p> - <a name="xml_text::empty"></a><a name="xml_text::unspecified_bool_type"></a>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> +<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> @@ -736,9 +731,9 @@ </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> -<p> - <a name="xml_text::get"></a>Given a text object, you can get the contents - (i.e. the value of PCDATA/CDATA node) by using the following function: +<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> @@ -746,11 +741,10 @@ In case text object is empty, the function returns an empty string - it never returns a null pointer. </p> -<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>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: +<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> @@ -767,9 +761,9 @@ 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> -<p> - <a name="xml_text::data"></a><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> +<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: @@ -787,6 +781,7 @@ 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"><<</span> <span class="string">"Project name: "</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">"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"><<</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"><<</span> <span class="string">"Project version: "</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">"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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> @@ -798,11 +793,11 @@ </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> +<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> -<p> - <a name="xml_node::root"></a>If you need to get the document root of some - node, you can use the following function: +<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> @@ -811,11 +806,10 @@ 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> -<p> - <a name="xml_node::path"></a><a name="xml_node::first_element_by_path"></a>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: +<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> @@ -860,13 +854,12 @@ is defined. </p></td></tr> </table></div> -<p> - <a name="xml_node::offset_debug"></a>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: +<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> @@ -890,7 +883,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: diff --git a/docs/manual/apiref.html b/docs/manual/apiref.html index 80e59e8..b9cbc77 100644 --- a/docs/manual/apiref.html +++ b/docs/manual/apiref.html @@ -4,15 +4,15 @@ <title>API Reference</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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> <link rel="prev" href="changes.html" title="Changelog"> <link rel="next" href="toc.html" title="Table of Contents"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: @@ -28,7 +28,7 @@ <hr> <div class="section"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="manual.apiref"></a><a class="link" href="apiref.html" title="API Reference">API Reference</a> +<a name="manual.apiref"></a><a class="link" href="apiref.html" title="API Reference"> API Reference</a> </h2></div></div></div> <p> This is the reference for all macros, types, enumerations, classes and functions @@ -130,6 +130,7 @@ </li> <li class="listitem"> <a class="link" href="dom.html#node_doctype">node_doctype</a> <br><br> + </li> </ul></div> </li> @@ -187,6 +188,7 @@ <li class="listitem"> <a class="link" href="loading.html#status_no_document_element">status_no_document_element</a> <br><br> + </li> </ul></div> </li> @@ -222,6 +224,7 @@ </li> <li class="listitem"> <a class="link" href="loading.html#encoding_latin1">encoding_latin1</a> <br><br> + </li> </ul></div> </li> @@ -273,6 +276,7 @@ </li> <li class="listitem"> <a class="link" href="saving.html#format_write_bom">format_write_bom</a> <br><br> + </li> </ul></div> </li> @@ -339,12 +343,14 @@ <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "> <li class="listitem"> <a class="link" href="dom.html#xml_attribute::ctor">xml_attribute</a><code class="computeroutput"><span class="special">();</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="dom.html#xml_attribute::empty">empty</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">operator</span> </code><a class="link" href="dom.html#xml_attribute::unspecified_bool_type">unspecified_bool_type</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="dom.html#xml_attribute::comparison">operator==</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&</span> @@ -376,21 +382,25 @@ <span class="identifier">r</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">size_t</span> </code><a class="link" href="dom.html#xml_attribute::hash_value">hash_value</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_attribute</span> </code><a class="link" href="access.html#xml_attribute::next_attribute">next_attribute</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_attribute</span> </code><a class="link" href="access.html#xml_attribute::previous_attribute">previous_attribute</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> </code><a class="link" href="access.html#xml_attribute::name">name</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> </code><a class="link" href="access.html#xml_attribute::value">value</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> </code><a class="link" href="access.html#xml_attribute::as_string">as_string</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> @@ -438,6 +448,7 @@ <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="modify.html#xml_attribute::set_name">set_name</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> @@ -469,6 +480,7 @@ <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_attribute</span><span class="special">&</span> @@ -503,6 +515,7 @@ <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span></code> <br><br> + </li> </ul></div> </li> @@ -512,12 +525,14 @@ <li class="listitem"> <a class="link" href="dom.html#xml_node::ctor">xml_node</a><code class="computeroutput"><span class="special">();</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="dom.html#xml_node::empty">empty</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">operator</span> </code><a class="link" href="dom.html#xml_node::unspecified_bool_type">unspecified_bool_type</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="dom.html#xml_node::comparison">operator==</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> @@ -549,20 +564,24 @@ <span class="identifier">r</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">size_t</span> </code><a class="link" href="dom.html#xml_node::hash_value">hash_value</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node_type</span> </code><a class="link" href="dom.html#xml_node::type">type</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> </code><a class="link" href="access.html#xml_node::name">name</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> </code><a class="link" href="access.html#xml_node::value">value</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="access.html#xml_node::parent">parent</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> @@ -578,12 +597,14 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="access.html#xml_node::previous_sibling">previous_sibling</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_attribute</span> </code><a class="link" href="access.html#xml_node::first_attribute">first_attribute</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_attribute</span> </code><a class="link" href="access.html#xml_node::last_attribute">last_attribute</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <span class="emphasis"><em>implementation-defined type</em></span> <a class="link" href="access.html#xml_node::children">children</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> @@ -595,6 +616,7 @@ </li> <li class="listitem"> <span class="emphasis"><em>implementation-defined type</em></span> <a class="link" href="access.html#xml_node::attributes">attributes</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="access.html#xml_node::child">child</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> @@ -626,6 +648,7 @@ <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="access.html#xml_node::find_child_by_attribute">find_child_by_attribute</a><code class="computeroutput"><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></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> </code><a class="link" href="access.html#xml_node::child_value">child_value</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> @@ -637,6 +660,7 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_text</span> </code><a class="link" href="access.html#xml_node::text">text</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">typedef</span> <span class="identifier">xml_node_iterator</span> @@ -647,6 +671,7 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">iterator</span> </code><a class="link" href="access.html#xml_node::end">end</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">typedef</span> <span class="identifier">xml_attribute_iterator</span> @@ -657,9 +682,11 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">attribute_iterator</span> </code><a class="link" href="access.html#xml_node::attributes_end">attributes_end</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="access.html#xml_node::traverse">traverse</a><code class="computeroutput"><span class="special">(</span><span class="identifier">xml_tree_walker</span><span class="special">&</span> <span class="identifier">walker</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Predicate</span><span class="special">></span> <span class="identifier">xml_attribute</span> @@ -679,6 +706,7 @@ <span class="identifier">pred</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">string_t</span> </code><a class="link" href="access.html#xml_node::path">path</a><code class="computeroutput"><span class="special">(</span><span class="identifier">char_t</span> @@ -697,6 +725,7 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">ptrdiff_t</span> </code><a class="link" href="access.html#xml_node::offset_debug">offset_debug</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="modify.html#xml_node::set_name">set_name</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> @@ -706,6 +735,7 @@ <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="modify.html#xml_node::set_value">set_value</a><code class="computeroutput"><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></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_attribute</span> </code><a class="link" href="modify.html#xml_node::append_attribute">append_attribute</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> @@ -724,6 +754,7 @@ <code class="computeroutput"><span class="identifier">xml_attribute</span> </code><a class="link" href="modify.html#xml_node::insert_attribute_before">insert_attribute_before</a><code class="computeroutput"><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">&</span> <span class="identifier">attr</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::append_child">append_child</a><code class="computeroutput"><span class="special">(</span><span class="identifier">xml_node_type</span> @@ -744,6 +775,7 @@ <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::insert_child_before">insert_child_before</a><code class="computeroutput"><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">&</span> <span class="identifier">node</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::append_child">append_child</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> @@ -762,6 +794,7 @@ <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::insert_child_before">insert_child_before</a><code class="computeroutput"><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">&</span> <span class="identifier">node</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_attribute</span> </code><a class="link" href="modify.html#xml_node::append_copy">append_copy</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&</span> <span class="identifier">proto</span><span class="special">);</span></code> @@ -779,6 +812,7 @@ <code class="computeroutput"><span class="identifier">xml_attribute</span> </code><a class="link" href="modify.html#xml_node::insert_copy_before">insert_copy_before</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&</span> <span class="identifier">proto</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::append_copy">append_copy</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> @@ -797,6 +831,26 @@ <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::insert_copy_before">insert_copy_before</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> <span class="identifier">proto</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> <span class="identifier">node</span><span class="special">);</span></code> <br><br> + + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::append_move">append_move</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> + <span class="identifier">moved</span><span class="special">);</span></code> + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::prepend_move">prepend_move</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> + <span class="identifier">moved</span><span class="special">);</span></code> + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::insert_move_after">insert_move_after</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> + <span class="identifier">moved</span><span class="special">,</span> + <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> <span class="identifier">node</span><span class="special">);</span></code> + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="modify.html#xml_node::insert_move_before">insert_move_before</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> + <span class="identifier">moved</span><span class="special">,</span> + <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</span> <span class="identifier">node</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="modify.html#xml_node::remove_attribute">remove_attribute</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_attribute</span><span class="special">&</span> @@ -814,6 +868,7 @@ <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="modify.html#xml_node::remove_child">remove_child</a><code class="computeroutput"><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></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_parse_result</span> </code><a class="link" href="modify.html#xml_node::append_buffer">append_buffer</a><code class="computeroutput"><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> @@ -823,6 +878,7 @@ <span class="identifier">encoding</span> <span class="special">=</span> <span class="identifier">encoding_auto</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">void</span> </code><a class="link" href="saving.html#xml_node::print">print</a><code class="computeroutput"><span class="special">(</span><span class="identifier">xml_writer</span><span class="special">&</span> <span class="identifier">writer</span><span class="special">,</span> <span class="keyword">const</span> @@ -863,17 +919,14 @@ <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> - <code class="computeroutput"><span class="identifier">xpath_node</span> </code><a class="link" href="xpath.html#xml_node::select_single_node">select_single_node</a><code class="computeroutput"><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></code> + <code class="computeroutput"><span class="identifier">xpath_node</span> </code><a class="link" href="xpath.html#xml_node::select_node">select_node</a><code class="computeroutput"><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></code> </li> <li class="listitem"> - <code class="computeroutput"><span class="identifier">xpath_node</span> </code><a class="link" href="xpath.html#xml_node::select_single_node_precomp">select_single_node</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_query</span><span class="special">&</span> + <code class="computeroutput"><span class="identifier">xpath_node</span> </code><a class="link" href="xpath.html#xml_node::select_node_precomp">select_node</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_query</span><span class="special">&</span> <span class="identifier">query</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> </li> @@ -890,6 +943,7 @@ <span class="identifier">query</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -901,6 +955,7 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="special">~</span></code><a class="link" href="dom.html#xml_document::dtor">xml_document</a><code class="computeroutput"><span class="special">();</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">void</span> </code><a class="link" href="dom.html#xml_document::reset">reset</a><code class="computeroutput"><span class="special">();</span></code> @@ -909,6 +964,7 @@ <code class="computeroutput"><span class="keyword">void</span> </code><a class="link" href="dom.html#xml_document::reset">reset</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xml_document</span><span class="special">&</span> <span class="identifier">proto</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_parse_result</span> </code><a class="link" href="loading.html#xml_document::load_stream">load</a><code class="computeroutput"><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span><span class="special">&</span> @@ -926,11 +982,16 @@ <span class="identifier">options</span> <span class="special">=</span> <span class="identifier">parse_default</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> - <code class="computeroutput"><span class="identifier">xml_parse_result</span> </code><a class="link" href="loading.html#xml_document::load_string">load</a><code class="computeroutput"><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></code> <br><br> + <code class="computeroutput"><span class="identifier">xml_parse_result</span> </code><a class="link" href="loading.html#xml_document::load_string">load_string</a><code class="computeroutput"><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></code> + <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_parse_result</span> </code><a class="link" href="loading.html#xml_document::load_file">load_file</a><code class="computeroutput"><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> @@ -947,6 +1008,7 @@ <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></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_parse_result</span> </code><a class="link" href="loading.html#xml_document::load_buffer">load_buffer</a><code class="computeroutput"><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> @@ -973,6 +1035,7 @@ <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></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="saving.html#xml_document::save_file">save_file</a><code class="computeroutput"><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> @@ -995,6 +1058,7 @@ <span class="identifier">encoding_auto</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">void</span> </code><a class="link" href="saving.html#xml_document::save_stream">save</a><code class="computeroutput"><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="identifier">stream</span><span class="special">,</span> <span class="keyword">const</span> @@ -1017,6 +1081,7 @@ <span class="identifier">format_default</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">void</span> </code><a class="link" href="saving.html#xml_document::save">save</a><code class="computeroutput"><span class="special">(</span><span class="identifier">xml_writer</span><span class="special">&</span> <span class="identifier">writer</span><span class="special">,</span> <span class="keyword">const</span> @@ -1028,9 +1093,11 @@ <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></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="dom.html#xml_document::document_element">document_element</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -1045,12 +1112,14 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_encoding</span> </code><a class="link" href="loading.html#xml_parse_result::encoding">encoding</a><code class="computeroutput"><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">operator</span> </code><a class="link" href="loading.html#xml_parse_result::bool">bool</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> </code><a class="link" href="loading.html#xml_parse_result::description">description</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -1060,6 +1129,7 @@ <li class="listitem"> <code class="computeroutput"><span class="keyword">class</span> </code><a class="link" href="access.html#xml_attribute_iterator">xml_attribute_iterator</a> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">class</span> </code><a class="link" href="access.html#xml_tree_walker">xml_tree_walker</a> @@ -1075,9 +1145,11 @@ <li class="listitem"> <code class="computeroutput"><span class="keyword">virtual</span> <span class="keyword">bool</span> </code><a class="link" href="access.html#xml_tree_walker::end">end</a><code class="computeroutput"><span class="special">(</span><span class="identifier">xml_node</span><span class="special">&</span> <span class="identifier">node</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">int</span> </code><a class="link" href="access.html#xml_tree_walker::depth">depth</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -1089,9 +1161,11 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">operator</span> </code><a class="link" href="access.html#xml_text::unspecified_bool_type">xml_text::unspecified_bool_type</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> </code><a class="link" href="access.html#xml_text::get">xml_text::get</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> </code><a class="link" href="access.html#xml_text::as_string">as_string</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> @@ -1139,11 +1213,13 @@ <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="modify.html#xml_text::set">set</a><code class="computeroutput"><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></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="modify.html#xml_text::set">set</a><code class="computeroutput"><span class="special">(</span><span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">);</span></code> @@ -1167,6 +1243,7 @@ <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_text</span><span class="special">&</span> @@ -1201,9 +1278,11 @@ <span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">rhs</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="access.html#xml_text::data">data</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -1214,12 +1293,14 @@ </code><a class="link" href="saving.html#xml_writer::write">write</a><code class="computeroutput"><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></code> <br><br> + </li></ul></div> </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">class</span> </code><a class="link" href="saving.html#xml_writer_file">xml_writer_file</a><code class="computeroutput"><span class="special">:</span> <span class="keyword">public</span> <span class="identifier">xml_writer</span></code> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"> <a class="link" href="saving.html#xml_writer_file">xml_writer_file</a><code class="computeroutput"><span class="special">(</span><span class="keyword">void</span><span class="special">*</span> <span class="identifier">file</span><span class="special">);</span></code> <br><br> + </li></ul></div> </li> <li class="listitem"> @@ -1230,6 +1311,7 @@ </li> <li class="listitem"> <a class="link" href="saving.html#xml_writer_stream">xml_writer_stream</a><code class="computeroutput"><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">wostream</span><span class="special">&</span> <span class="identifier">stream</span><span class="special">);</span></code> <br><br> + </li> </ul></div> </li> @@ -1247,6 +1329,7 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> </code><a class="link" href="xpath.html#xpath_parse_result::description">description</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -1260,6 +1343,7 @@ <span class="identifier">variables</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="xpath.html#xpath_query::evaluate_boolean">evaluate_boolean</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> @@ -1285,16 +1369,24 @@ <code class="computeroutput"><span class="identifier">xpath_node_set</span> </code><a class="link" href="xpath.html#xpath_query::evaluate_node_set">evaluate_node_set</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> + </li> +<li class="listitem"> + <code class="computeroutput"><span class="identifier">xpath_node</span> </code><a class="link" href="xpath.html#xpath_query::evaluate_node">evaluate_node</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> + <span class="identifier">n</span><span class="special">)</span> + <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xpath_value_type</span> </code><a class="link" href="xpath.html#xpath_query::return_type">return_type</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">xpath_parse_result</span><span class="special">&</span> </code><a class="link" href="xpath.html#xpath_query::result">result</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">operator</span> </code><a class="link" href="xpath.html#xpath_query::unspecified_bool_type">unspecified_bool_type</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -1307,9 +1399,11 @@ </code><a class="link" href="xpath.html#xpath_exception::what">what</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">throw</span><span class="special">();</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">xpath_parse_result</span><span class="special">&</span> </code><a class="link" href="xpath.html#xpath_exception::result">result</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -1327,6 +1421,7 @@ <span class="identifier">xml_node</span><span class="special">&</span> <span class="identifier">parent</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="xpath.html#xpath_node::node">node</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> @@ -1337,6 +1432,7 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xml_node</span> </code><a class="link" href="xpath.html#xpath_node::parent">parent</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">operator</span> </code><a class="link" href="xpath.html#xpath_node::unspecified_bool_type">unspecified_bool_type</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> @@ -1351,6 +1447,7 @@ <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -1367,6 +1464,7 @@ <span class="identifier">type</span> <span class="special">=</span> <span class="identifier">type_unsorted</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">typedef</span> <span class="keyword">const</span> @@ -1381,6 +1479,7 @@ <code class="computeroutput"><span class="identifier">const_iterator</span> </code><a class="link" href="xpath.html#xpath_node_set::end">end</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">xpath_node</span><span class="special">&</span> </code><a class="link" href="xpath.html#xpath_node_set::index">operator[]</a><code class="computeroutput"><span class="special">(</span><span class="identifier">size_t</span> @@ -1392,11 +1491,13 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="xpath.html#xpath_node_set::empty">empty</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xpath_node</span> </code><a class="link" href="xpath.html#xpath_node_set::first">first</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">enum</span> <span class="identifier">type_t</span> @@ -1411,6 +1512,7 @@ <code class="computeroutput"><span class="keyword">void</span> </code><a class="link" href="xpath.html#xpath_node_set::sort">sort</a><code class="computeroutput"><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></code> <br><br> + </li> </ul></div> </li> @@ -1424,6 +1526,7 @@ <code class="computeroutput"><span class="identifier">xpath_value_type</span> </code><a class="link" href="xpath.html#xpath_variable::type">type</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="xpath.html#xpath_variable::get_boolean">get_boolean</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> @@ -1436,6 +1539,7 @@ </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">xpath_node_set</span><span class="special">&</span> </code><a class="link" href="xpath.html#xpath_variable::get_node_set">get_node_set</a><code class="computeroutput"><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="xpath.html#xpath_variable::set">set</a><code class="computeroutput"><span class="special">(</span><span class="keyword">bool</span> <span class="identifier">value</span><span class="special">);</span></code> @@ -1452,6 +1556,7 @@ <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="xpath.html#xpath_variable::set">set</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_node_set</span><span class="special">&</span> <span class="identifier">value</span><span class="special">);</span></code> <br><br> + </li> </ul></div> </li> @@ -1463,6 +1568,7 @@ </code><a class="link" href="xpath.html#xpath_variable_set::add">add</a><code class="computeroutput"><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></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="xpath.html#xpath_variable_set::set">set</a><code class="computeroutput"><span class="special">(</span><span class="keyword">const</span> <span class="identifier">char_t</span><span class="special">*</span> @@ -1483,6 +1589,7 @@ <code class="computeroutput"><span class="keyword">bool</span> </code><a class="link" href="xpath.html#xpath_variable_set::set">set</a><code class="computeroutput"><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">&</span> <span class="identifier">value</span><span class="special">);</span></code> <br><br> + </li> <li class="listitem"> <code class="computeroutput"><span class="identifier">xpath_variable</span><span class="special">*</span> @@ -1494,6 +1601,7 @@ <span class="identifier">name</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></code> <br><br> + </li> </ul></div> </li> @@ -1539,7 +1647,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: diff --git a/docs/manual/changes.html b/docs/manual/changes.html index 58dc474..a3495b2 100644 --- a/docs/manual/changes.html +++ b/docs/manual/changes.html @@ -4,15 +4,15 @@ <title>Changelog</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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> <link rel="prev" href="xpath.html" title="XPath"> <link rel="next" 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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: @@ -28,12 +28,114 @@ <hr> <div class="section"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="manual.changes"></a><a class="link" href="changes.html" title="Changelog">Changelog</a> +<a name="manual.changes"></a><a class="link" href="changes.html" title="Changelog"> Changelog</a> </h2></div></div></div> -<h6> -<a name="manual.changes.h0"></a> - <span class="phrase"><a name="manual.changes.27_02_2014___version_1_4"></a></span><a class="link" href="changes.html#manual.changes.27_02_2014___version_1_4">27.02.2014 - - version 1.4</a> +<a name="manual.changes.27_11_2014___version_1_5"></a><h6> + <a class="link" href="changes.html#manual.changes.27_11_2014___version_1_5">27.11.2014 - version + 1.5</a> + </h6> +<p> + Major release, featuring a lot of performance improvements and some new features. + </p> +<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> +<li class="listitem"> + Specification changes: + <div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + xml_document::load(const char_t*) was renamed to load_string; the + old method is still available and will be deprecated in a future + release + </li> +<li class="listitem"> + xml_node::select_single_node was renamed to select_node; the old + method is still available and will be deprecated in a future release. + </li> +</ol></div> + </li> +<li class="listitem"> + New features: + <div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + Added xml_node::append_move and other functions for moving nodes + within a document + </li> +<li class="listitem"> + Added xpath_query::evaluate_node for evaluating queries with a single + node as a result + </li> +</ol></div> + </li> +<li class="listitem"> + Performance improvements: + <div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + Optimized XML parsing (10-40% faster with clang/gcc, up to 10% faster + with MSVC) + </li> +<li class="listitem"> + Optimized memory consumption when copying nodes in the same document + (string contents is now shared) + </li> +<li class="listitem"> + Optimized node copying (10% faster for cross-document copies, 3x + faster for inter-document copies; also it now consumes a constant + amount of stack space) + </li> +<li class="listitem"> + Optimized node output (60% faster; also it now consumes a constant + amount of stack space) + </li> +<li class="listitem"> + Optimized XPath allocation (query evaluation now results in fewer + temporary allocations) + </li> +<li class="listitem"> + Optimized XPath sorting (node set sorting is 2-3x faster in some + cases) + </li> +<li class="listitem"> + Optimized XPath evaluation (XPathMark suite is 100x faster; some + commonly used queries are 3-4x faster) + </li> +</ol></div> + </li> +<li class="listitem"> + Compatibility improvements: + <div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + Fixed xml_node::offset_debug for corner cases + </li> +<li class="listitem"> + Fixed undefined behavior while calling memcpy in some cases + </li> +<li class="listitem"> + Fixed MSVC 2015 compilation warnings + </li> +<li class="listitem"> + Fixed contrib/foreach.hpp for Boost 1.56.0 + </li> +</ol></div> + </li> +<li class="listitem"> + Bug fixes + <div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + Adjusted comment output to avoid malformed documents if the comment + value contains "--" + </li> +<li class="listitem"> + Fix XPath sorting for documents that were constructed using append_buffer + </li> +<li class="listitem"> + Fix load_file for wide-character paths with non-ASCII characters + in MinGW with C++11 mode enabled + </li> +</ol></div> + </li> +</ul></div> +<a name="manual.changes.27_02_2014___version_1_4"></a><h6> + <a class="link" href="changes.html#manual.changes.27_02_2014___version_1_4">27.02.2014 - version + 1.4</a> </h6> <p> Major release, featuring various new features, bug fixes and compatibility @@ -113,10 +215,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h1"></a> - <span class="phrase"><a name="manual.changes.1_05_2012___version_1_2"></a></span><a class="link" href="changes.html#manual.changes.1_05_2012___version_1_2">1.05.2012 - - version 1.2</a> +<a name="manual.changes.1_05_2012___version_1_2"></a><h6> + <a class="link" href="changes.html#manual.changes.1_05_2012___version_1_2">1.05.2012 - version + 1.2</a> </h6> <p> Major release, featuring header-only mode, various interface enhancements (i.e. @@ -208,10 +309,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h2"></a> - <span class="phrase"><a name="manual.changes.1_11_2010___version_1_0"></a></span><a class="link" href="changes.html#manual.changes.1_11_2010___version_1_0">1.11.2010 - - version 1.0</a> +<a name="manual.changes.1_11_2010___version_1_0"></a><h6> + <a class="link" href="changes.html#manual.changes.1_11_2010___version_1_0">1.11.2010 - version + 1.0</a> </h6> <p> Major release, featuring many XPath enhancements, wide character filename support, @@ -427,10 +527,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h3"></a> - <span class="phrase"><a name="manual.changes.1_07_2010___version_0_9"></a></span><a class="link" href="changes.html#manual.changes.1_07_2010___version_0_9">1.07.2010 - - version 0.9</a> +<a name="manual.changes.1_07_2010___version_0_9"></a><h6> + <a class="link" href="changes.html#manual.changes.1_07_2010___version_0_9">1.07.2010 - version + 0.9</a> </h6> <p> Major release, featuring extended and improved Unicode support, miscellaneous @@ -549,10 +648,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h4"></a> - <span class="phrase"><a name="manual.changes.8_11_2009___version_0_5"></a></span><a class="link" href="changes.html#manual.changes.8_11_2009___version_0_5">8.11.2009 - - version 0.5</a> +<a name="manual.changes.8_11_2009___version_0_5"></a><h6> + <a class="link" href="changes.html#manual.changes.8_11_2009___version_0_5">8.11.2009 - version + 0.5</a> </h6> <p> Major bugfix release. Changes: @@ -661,10 +759,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h5"></a> - <span class="phrase"><a name="manual.changes.17_09_2009___version_0_42"></a></span><a class="link" href="changes.html#manual.changes.17_09_2009___version_0_42">17.09.2009 - - version 0.42</a> +<a name="manual.changes.17_09_2009___version_0_42"></a><h6> + <a class="link" href="changes.html#manual.changes.17_09_2009___version_0_42">17.09.2009 - version + 0.42</a> </h6> <p> Maintenance release. Changes: @@ -707,10 +804,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h6"></a> - <span class="phrase"><a name="manual.changes.8_02_2009___version_0_41"></a></span><a class="link" href="changes.html#manual.changes.8_02_2009___version_0_41">8.02.2009 - - version 0.41</a> +<a name="manual.changes.8_02_2009___version_0_41"></a><h6> + <a class="link" href="changes.html#manual.changes.8_02_2009___version_0_41">8.02.2009 - version + 0.41</a> </h6> <p> Maintenance release. Changes: @@ -722,10 +818,9 @@ to output stream) </li></ol></div> </li></ul></div> -<h6> -<a name="manual.changes.h7"></a> - <span class="phrase"><a name="manual.changes.18_01_2009___version_0_4"></a></span><a class="link" href="changes.html#manual.changes.18_01_2009___version_0_4">18.01.2009 - - version 0.4</a> +<a name="manual.changes.18_01_2009___version_0_4"></a><h6> + <a class="link" href="changes.html#manual.changes.18_01_2009___version_0_4">18.01.2009 - version + 0.4</a> </h6> <p> Changes: @@ -801,10 +896,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h8"></a> - <span class="phrase"><a name="manual.changes.31_10_2007___version_0_34"></a></span><a class="link" href="changes.html#manual.changes.31_10_2007___version_0_34">31.10.2007 - - version 0.34</a> +<a name="manual.changes.31_10_2007___version_0_34"></a><h6> + <a class="link" href="changes.html#manual.changes.31_10_2007___version_0_34">31.10.2007 - version + 0.34</a> </h6> <p> Maintenance release. Changes: @@ -840,10 +934,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h9"></a> - <span class="phrase"><a name="manual.changes.21_02_2007___version_0_3"></a></span><a class="link" href="changes.html#manual.changes.21_02_2007___version_0_3">21.02.2007 - - version 0.3</a> +<a name="manual.changes.21_02_2007___version_0_3"></a><h6> + <a class="link" href="changes.html#manual.changes.21_02_2007___version_0_3">21.02.2007 - version + 0.3</a> </h6> <p> Refactored, reworked and improved version. Changes: @@ -902,10 +995,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h10"></a> - <span class="phrase"><a name="manual.changes.6_11_2006___version_0_2"></a></span><a class="link" href="changes.html#manual.changes.6_11_2006___version_0_2">6.11.2006 - - version 0.2</a> +<a name="manual.changes.6_11_2006___version_0_2"></a><h6> + <a class="link" href="changes.html#manual.changes.6_11_2006___version_0_2">6.11.2006 - version + 0.2</a> </h6> <p> First public release. Changes: @@ -937,10 +1029,9 @@ </ol></div> </li> </ul></div> -<h6> -<a name="manual.changes.h11"></a> - <span class="phrase"><a name="manual.changes.15_07_2006___version_0_1"></a></span><a class="link" href="changes.html#manual.changes.15_07_2006___version_0_1">15.07.2006 - - version 0.1</a> +<a name="manual.changes.15_07_2006___version_0_1"></a><h6> + <a class="link" href="changes.html#manual.changes.15_07_2006___version_0_1">15.07.2006 - version + 0.1</a> </h6> <p> First private release for testing purposes @@ -956,7 +1047,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: diff --git a/docs/manual/dom.html b/docs/manual/dom.html index 57d3ea0..3d7cd29 100644 --- a/docs/manual/dom.html +++ b/docs/manual/dom.html @@ -4,15 +4,15 @@ <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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> <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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: @@ -28,20 +28,20 @@ <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> +<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> +<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 +<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 +<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> @@ -56,7 +56,7 @@ </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> +<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 @@ -66,9 +66,9 @@ which correspond to C++ type <a class="link" href="dom.html#xml_attribute">xml_attribute</a>, and some additional data (i.e. name). </p> -<p> - <a name="xml_node_type"></a>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>): +<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"> @@ -81,6 +81,7 @@ 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 @@ -188,7 +189,7 @@ (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"><!</span><span class="identifier">DOCTYPE</span> <span class="identifier">greeting</span> <span class="special">[</span> <span class="special"><!</span><span class="identifier">ELEMENT</span> <span class="identifier">greeting</span> <span class="special">(#</span><span class="identifier">PCDATA</span><span class="special">)></span> <span class="special">]></span> +<pre class="programlisting"><span class="special"><!</span><span class="identifier">DOCTYPE</span> <span class="identifier">greeting</span> <span class="special">[</span> <span class="special"><!</span><span class="identifier">ELEMENT</span> <span class="identifier">greeting</span> <span class="special">(</span><span class="preprocessor">#PCDATA</span><span class="special">)></span> <span class="special">]></span> </pre> <div class="blockquote"><blockquote class="blockquote"><p> Here the node has value <code class="computeroutput"><span class="string">"greeting [ <!ELEMENT @@ -208,6 +209,7 @@ <tbody><tr> <td> <p> + </p> <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="special"><?</span><span class="identifier">xml</span> <span class="identifier">version</span><span class="special">=</span><span class="string">"1.0"</span><span class="special">?></span> <span class="special"><</span><span class="identifier">mesh</span> <span class="identifier">name</span><span class="special">=</span><span class="string">"mesh_root"</span><span class="special">></span> @@ -235,7 +237,7 @@ </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> +<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> @@ -259,18 +261,21 @@ 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> -<p> - <a name="xml_document"></a><a name="xml_document::document_element"></a><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. +<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> -<p> - <a name="xml_document::ctor"></a><a name="xml_document::dtor"></a><a name="xml_document::reset"></a>Default constructor of <code class="computeroutput"><span class="identifier">xml_document</span></code> +<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 @@ -295,12 +300,12 @@ are destroyed. </p></td></tr> </table></div> -<p> - <a name="xml_node"></a><a name="xml_node::type"></a><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> +<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> @@ -310,8 +315,8 @@ 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> -<p> - <a name="node_null"></a>There is a special value of <code class="computeroutput"><span class="identifier">xml_node</span></code> +<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 @@ -321,40 +326,37 @@ 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> -<p> - <a name="xml_attribute"></a><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. +<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> -<p> - <a name="xml_attribute::ctor"></a><a name="xml_node::ctor"></a>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. +<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> -<p> - <a name="xml_attribute::comparison"></a><a name="xml_node::comparison"></a><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). +<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> -<p> - <a name="xml_attribute::hash_value"></a><a name="xml_node::hash_value"></a>If - you want to use <code class="computeroutput"><span class="identifier">xml_node</span></code> +<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> -<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>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> +<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>. @@ -377,14 +379,14 @@ </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> +<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 + 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 @@ -416,13 +418,13 @@ <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> -<p> - <a name="char_t"></a><a name="string_t"></a>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. +<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 @@ -434,10 +436,9 @@ inconvenient to process and most of your XML data is non-ASCII, wchar_t mode is probably a better choice. </p> -<p> - <a name="as_utf8"></a><a name="as_wide"></a>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: +<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> @@ -484,7 +485,7 @@ </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> +<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: @@ -510,13 +511,13 @@ <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 + 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> +<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. @@ -540,7 +541,7 @@ </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> +<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 @@ -549,22 +550,21 @@ </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 +<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> -<p> - <a name="allocation_function"></a><a name="deallocation_function"></a>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: +<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> -<p> - <a name="set_memory_management_functions"></a><a name="get_memory_allocation_function"></a><a name="get_memory_deallocation_function"></a>You can use the following accessor - functions to change or get current memory management functions: +<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> @@ -589,6 +589,7 @@ 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> @@ -603,6 +604,7 @@ <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> @@ -617,7 +619,7 @@ </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> +<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 @@ -629,7 +631,7 @@ </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 + <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; "> @@ -640,6 +642,7 @@ 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> @@ -649,6 +652,7 @@ 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> @@ -663,7 +667,7 @@ </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 +<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> @@ -673,7 +677,7 @@ </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 + 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 @@ -711,7 +715,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: diff --git a/docs/manual/install.html b/docs/manual/install.html index 5675651..af662c1 100644 --- a/docs/manual/install.html +++ b/docs/manual/install.html @@ -4,15 +4,15 @@ <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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> -<link rel="prev" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> +<link rel="prev" href="../manual.html" title="pugixml 1.5"> <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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <b>Installation</b> | Document: @@ -28,48 +28,48 @@ <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> +<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> +<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.subversion">Subversion repository</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.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> +<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 +<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 +<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 +<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 +<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> +<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> +<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 checkout the Subversion repository. + 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> +<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.4/pugixml-1.4.zip" target="_top">https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.zip</a> -<a href="https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.tar.gz" target="_top">https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.tar.gz</a> +<pre class="programlisting"><a href="https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.zip" target="_top">https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.zip</a> +<a href="https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.tar.gz" target="_top">https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.tar.gz</a> </pre> <p> The distribution contains library source, documentation (the manual you're @@ -80,56 +80,54 @@ 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="http://code.google.com/p/pugixml/downloads/list" target="_top">version + 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.subversion"></a><a class="link" href="install.html#manual.install.getting.subversion" title="Subversion repository">Subversion repository</a> +<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 Subversion repository is located at <a href="http://pugixml.googlecode.com/svn/" target="_top">http://pugixml.googlecode.com/svn/</a>. - There is a Subversion tag "release-{version}" for each version; - also there is the "latest" tag, which always points to the latest - stable release. + 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">svn checkout http://pugixml.googlecode.com/svn/tags/release-1.4 pugixml</pre> -<p> - To checkout the latest version, you can use this command: - </p> -<pre class="programlisting">svn checkout http://pugixml.googlecode.com/svn/tags/latest pugixml</pre> +<pre class="programlisting">git clone https://github.com/zeux/pugixml +cd pugixml +git checkout v1.5 +</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 via - <code class="literal">svn update</code>. Use other tags if you want to switch to - new versions only explicitly (for example, using <code class="literal">svn switch</code> - command). Also please note that Subversion trunk contains the work-in-progress - version of the code; while this means that you can get new features and - bug fixes from trunk without waiting for a new release, this also means - that occasionally the code can be broken in some configurations. + 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.git"></a><a class="link" href="install.html#manual.install.getting.git" title="Git repository">Git repository</a> +<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> - The Subversion repository is mirrored by a Git repository at <a href="https://github.com/zeux/pugixml" target="_top">https://github.com/zeux/pugixml</a>. - The mirror is frequently updated and has the same structure in terms of - tags and contents as Subversion repository. + 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.5 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> +<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 @@ -139,7 +137,7 @@ 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 + <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> @@ -149,7 +147,7 @@ </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 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> @@ -184,7 +182,7 @@ </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 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> @@ -194,7 +192,7 @@ 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>. + 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 @@ -247,7 +245,7 @@ </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 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> @@ -282,10 +280,10 @@ </p></td></tr> </table></div> </div> -<div class="section"> +<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 name="PUGIXML_HEADER_ONLY"></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> +<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 @@ -324,7 +322,7 @@ <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 + 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> @@ -336,7 +334,7 @@ </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 +<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> @@ -358,7 +356,7 @@ 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. + 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. @@ -388,7 +386,7 @@ 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 + 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"> @@ -406,7 +404,7 @@ <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>. + 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 @@ -422,7 +420,7 @@ </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> +<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 @@ -502,7 +500,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <b>Installation</b> | Document: diff --git a/docs/manual/loading.html b/docs/manual/loading.html index e18cde6..d302f73 100644 --- a/docs/manual/loading.html +++ b/docs/manual/loading.html @@ -4,15 +4,15 @@ <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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> <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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: @@ -28,16 +28,16 @@ <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> +<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> +<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 @@ -49,26 +49,25 @@ 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 + 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>) + 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>. + 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> +<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> -<p> - <a name="xml_document::load_file"></a><a name="xml_document::load_file_wide"></a>The - most common source of XML data is files; pugixml provides dedicated functions +<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> @@ -76,8 +75,8 @@ </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 + 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. @@ -95,12 +94,13 @@ 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. + 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> @@ -113,19 +113,19 @@ </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> +<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> -<p> - <a name="xml_document::load_buffer"></a><a name="xml_document::load_buffer_inplace"></a><a name="xml_document::load_buffer_inplace_own"></a>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: +<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> @@ -135,7 +135,7 @@ 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>). + 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> @@ -163,12 +163,11 @@ is the recommended function if you have to load the document from memory and performance is critical. </p> -<p> - <a name="xml_document::load_string"></a>There is also a simple helper function - for cases when you want to load the XML document from null-terminated character - string: +<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</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 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> @@ -184,6 +183,7 @@ (<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">"<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>"</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> @@ -191,57 +191,61 @@ <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 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> +<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">// 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> +<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"><</span><span class="keyword">char</span><span class="special">*>(</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> +<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"><</span><span class="keyword">char</span><span class="special">*>(</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> +<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</span><span class="special">(</span><span class="string">"<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>"</span><span class="special">);</span> +<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">"<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>"</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> +<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> -<p> - <a name="xml_document::load_stream"></a>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: +<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">&</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">&</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> @@ -271,6 +275,7 @@ 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> @@ -280,14 +285,12 @@ </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> +<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> -<p> - <a name="xml_parse_result"></a>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: +<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> @@ -299,9 +302,8 @@ <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> -<p> - <a name="xml_parse_status"></a><a name="xml_parse_result::status"></a>Parsing - status is represented as the <code class="computeroutput"><span class="identifier">xml_parse_status</span></code> +<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; "> @@ -309,6 +311,7 @@ <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 @@ -327,6 +330,7 @@ <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 @@ -373,12 +377,14 @@ indicates an empty or invalid document </li> </ul></div> -<p> - <a name="xml_parse_result::description"></a><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> +<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. @@ -393,18 +399,16 @@ 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">></span><span class="identifier">some</span> <span class="identifier">data</span><span class="special"></</span><span class="identifier">node</span><span class="special">></span></code>. </p> -<p> - <a name="xml_parse_result::offset"></a>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). +<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> @@ -417,17 +421,16 @@ track the error position. </p></td></tr> </table></div> -<p> - <a name="xml_parse_result::encoding"></a>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> -<p> - <a name="xml_parse_result::bool"></a>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>: +<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> @@ -435,9 +438,10 @@ 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</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">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"><<</span> <span class="string">"XML ["</span> <span class="special"><<</span> <span class="identifier">source</span> <span class="special"><<</span> <span class="string">"] parsed without errors, attr value: ["</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">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"><<</span> <span class="string">"]\n\n"</span><span class="special">;</span> @@ -453,7 +457,7 @@ </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> +<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 @@ -485,12 +489,14 @@ 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 @@ -498,18 +504,21 @@ 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"><?</span><span class="identifier">xml</span> <span class="special">...?></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 @@ -518,6 +527,7 @@ 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 @@ -536,6 +546,7 @@ 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 @@ -554,6 +565,7 @@ 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 @@ -598,6 +610,7 @@ 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 @@ -607,6 +620,7 @@ 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 @@ -617,6 +631,7 @@ 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 @@ -656,6 +671,7 @@ 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, @@ -665,6 +681,7 @@ 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 @@ -681,23 +698,24 @@ 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">"<!--comment--><node>&lt;</node>"</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 &lt; is expanded</span> -<span class="identifier">doc</span><span class="special">.</span><span class="identifier">load</span><span class="special">(</span><span class="identifier">source</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 &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"><<</span> <span class="string">"First node value: ["</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">value</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"], node child value: ["</span> <span class="special"><<</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"><<</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</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="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"><<</span> <span class="string">"First node value: ["</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">value</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"], node child value: ["</span> <span class="special"><<</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"><<</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; &lt; is not expanded</span> -<span class="identifier">doc</span><span class="special">.</span><span class="identifier">load</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">&</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="comment">// Parsing with additional parse_comments option and without the (default) parse_escapes option; &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">&</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"><<</span> <span class="string">"First node value: ["</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">value</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"], node child value: ["</span> <span class="special"><<</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"><<</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 &lt; is not expanded</span> -<span class="identifier">doc</span><span class="special">.</span><span class="identifier">load</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="comment">// Parsing with minimal option mask; comment node is not added to the tree, and &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"><<</span> <span class="string">"First node value: ["</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">value</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"], node child value: ["</span> <span class="special"><<</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"><<</span> <span class="string">"]\n"</span><span class="special">;</span> </pre> <p> @@ -705,15 +723,14 @@ </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> +<a name="manual.loading.encoding"></a><a class="link" href="loading.html#manual.loading.encoding" title="Encodings"> Encodings</a> </h3></div></div></div> -<p> - <a name="xml_encoding"></a>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>, +<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; "> @@ -751,6 +768,7 @@ </li> <li class="listitem"> Otherwise encoding is assumed to be UTF-8. <br><br> + </li> </ul></div> </li> @@ -822,7 +840,7 @@ </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> +<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, @@ -879,7 +897,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: diff --git a/docs/manual/modify.html b/docs/manual/modify.html index 05b0fbe..5e44d90 100644 --- a/docs/manual/modify.html +++ b/docs/manual/modify.html @@ -4,15 +4,15 @@ <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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> <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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: @@ -28,16 +28,17 @@ <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> +<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.fragments">Assembling document from fragments</a></span></dt> +<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 @@ -61,12 +62,11 @@ </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> +<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> -<p> - <a name="xml_node::set_name"></a><a name="xml_node::set_value"></a>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> +<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>, @@ -98,31 +98,31 @@ 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"><<</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="comment">// change node name +</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><<</span> <span class="string">", new node name: "</span> <span class="special"><<</span> <span class="identifier">node</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">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"><<</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="comment">// change comment text +</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><<</span> <span class="string">", new comment text: "</span> <span class="special"><<</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"><<</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"><<</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"><<</span> <span class="string">", "</span> <span class="special"><<</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"><<</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"><<</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"><<</span> <span class="string">", "</span> <span class="special"><<</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"><<</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> +<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> -<p> - <a name="xml_attribute::set_name"></a><a name="xml_attribute::set_value"></a>All - attributes have name and value, both of which are strings (value may be empty). - You can set them with the following functions: +<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> @@ -177,8 +177,8 @@ including string conversions. </p></td></tr> </table></div> -<p> - <a name="xml_attribute::assign"></a>For convenience, all <code class="computeroutput"><span class="identifier">set_value</span></code> +<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">&</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> @@ -199,19 +199,20 @@ 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"><<</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"><<</span> <span class="string">", "</span> <span class="special"><<</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="comment">// change attribute name/value +</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><<</span> <span class="string">", "</span> <span class="special"><<</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"><<</span> <span class="string">", new attribute: "</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="special"><<</span> <span class="string">"="</span> <span class="special"><<</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">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="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"><<</span> <span class="string">"new attribute value: "</span> <span class="special"><<</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">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="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"><<</span> <span class="string">"final attribute value: "</span> <span class="special"><<</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">endl</span><span class="special">;</span> </pre> <p> @@ -219,11 +220,10 @@ </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> +<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> -<p> - <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>Nodes - and attributes do not exist without a document tree, so you can't create +<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> @@ -317,19 +317,20 @@ 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> +<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="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 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="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> @@ -338,11 +339,10 @@ </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> +<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> -<p> - <a name="xml_node::remove_attribute"></a><a name="xml_node::remove_child"></a>If - you do not want your document to contain some node or attribute, you can +<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">&</span> <span class="identifier">a</span><span class="special">);</span> @@ -394,17 +394,18 @@ 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> +<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="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="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> @@ -412,7 +413,7 @@ </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> +<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>, @@ -421,8 +422,8 @@ documentation for accessing document data</a>; this section describes the modification interface of <code class="computeroutput"><span class="identifier">xml_text</span></code>. </p> -<p> - <a name="xml_text::set"></a>Once you have an <code class="computeroutput"><span class="identifier">xml_text</span></code> +<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> @@ -439,9 +440,9 @@ 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> -<p> - <a name="xml_text::set_value"></a>In addition to a string function, several - functions are provided for handling text with numbers and booleans as contents: +<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> @@ -457,8 +458,8 @@ functions. You can <a class="link" href="modify.html#xml_attribute::set_value">refer to documentation for the attribute functions</a> for details. </p> -<p> - <a name="xml_text::assign"></a>For convenience, all <code class="computeroutput"><span class="identifier">set</span></code> +<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">&</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> @@ -480,29 +481,30 @@ 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> +<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> +<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> +<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> -<p> - <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>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: +<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">&</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">&</span> <span class="identifier">proto</span><span class="special">);</span> @@ -559,6 +561,7 @@ 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">&</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> @@ -570,23 +573,23 @@ <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="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">// 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="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="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> @@ -603,8 +606,8 @@ <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">&</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 <?include?></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 <?include?> +</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> @@ -613,13 +616,64 @@ </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> +<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">&</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">&</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">&</span> <span class="identifier">moved</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</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">&</span> <span class="identifier">moved</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">xml_node</span><span class="special">&</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> - <a name="xml_node::append_buffer"></a>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: + 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 @@ -668,10 +722,10 @@ - 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> -<p> - <a name="status_append_invalid_root"></a>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> +<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> @@ -687,7 +741,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: diff --git a/docs/manual/saving.html b/docs/manual/saving.html index 2c05a7b..7157d84 100644 --- a/docs/manual/saving.html +++ b/docs/manual/saving.html @@ -4,15 +4,15 @@ <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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> <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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: @@ -28,16 +28,16 @@ <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> +<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> +<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 @@ -46,8 +46,8 @@ 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 + 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> @@ -68,20 +68,19 @@ </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> +<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> -<p> - <a name="xml_document::save_file"></a><a name="xml_document::save_file_wide"></a>If - you want to save the whole document to a file, you can use one of the following - functions: +<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 + 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. @@ -93,39 +92,38 @@ 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> - <a name="xml_writer_file"></a><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> +<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. + 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"><<</span> <span class="string">"Saving result: "</span> <span class="special"><<</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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +<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"><<</span> <span class="string">"Saving result: "</span> <span class="special"><<</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"><<</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> +<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> -<p> - <a name="xml_document::save_stream"></a>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> +<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> @@ -145,19 +143,20 @@ 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> -<p> - <a name="xml_writer_stream"></a>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 +<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"><<</span> <span class="string">"Document:\n"</span><span class="special">;</span> +<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"><<</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> @@ -165,11 +164,10 @@ </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> +<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> -<p> - <a name="xml_document::save"></a><a name="xml_writer"></a><a name="xml_writer::write"></a>All - of the above saving functions are implemented in terms of writer interface. +<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> @@ -205,6 +203,7 @@ 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> @@ -221,11 +220,10 @@ </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> +<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> -<p> - <a name="xml_node::print"></a><a name="xml_node::print_stream"></a>While - the previously described functions save the whole document to the destination, +<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">&</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> @@ -248,21 +246,22 @@ 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</span><span class="special">(</span><span class="string">"<foo bar='baz'><call>hey</call></foo>"</span><span class="special">);</span> +<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">"<foo bar='baz'><call>hey</call></foo>"</span><span class="special">);</span> -<span class="comment">// print document to standard output (prints <?xml version="1.0"?><foo bar="baz"><call>hey</call></foo>)</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="comment">// print document to standard output (prints <?xml version="1.0"?><foo bar="baz"><call>hey</call></foo>) +</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"><<</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 <foo bar="baz"><call>hey</call></foo>)</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="comment">// print document to standard output as a regular node (prints <foo bar="baz"><call>hey</call></foo>) +</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"><<</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 <call>hey</call>)</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="comment">// print a subtree to standard output (prints <call>hey</call>) +</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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> </pre> <p> @@ -270,7 +269,7 @@ </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> +<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>. @@ -302,6 +301,7 @@ 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 @@ -312,6 +312,7 @@ 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 @@ -337,6 +338,7 @@ 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 @@ -372,43 +374,44 @@ 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</span><span class="special">(</span><span class="string">"<foo bar='baz'><call>hey</call></foo>"</span><span class="special">);</span> +<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">"<foo bar='baz'><call>hey</call></foo>"</span><span class="special">);</span> -<span class="comment">// default options; prints</span> -<span class="comment">// <?xml version="1.0"?></span> -<span class="comment">// <foo bar="baz"></span> -<span class="comment">// <call>hey</call></span> -<span class="comment">// </foo></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="comment">// default options; prints +</span><span class="comment">// <?xml version="1.0"?> +</span><span class="comment">// <foo bar="baz"> +</span><span class="comment">// <call>hey</call> +</span><span class="comment">// </foo> +</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"><<</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">// <?xml version="1.0"?></span> -<span class="comment">// <foo bar="baz"></span> -<span class="comment">// --<call>hey</call></span> -<span class="comment">// </foo></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="comment">// default options with custom indentation string; prints +</span><span class="comment">// <?xml version="1.0"?> +</span><span class="comment">// <foo bar="baz"> +</span><span class="comment">// --<call>hey</call> +</span><span class="comment">// </foo> +</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"><<</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">// <?xml version="1.0"?></span> -<span class="comment">// <foo bar="baz"></span> -<span class="comment">// <call>hey</call></span> -<span class="comment">// </foo></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">&</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"><<</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">// <?xml version="1.0"?> +</span><span class="comment">// <foo bar="baz"> +</span><span class="comment">// <call>hey</call> +</span><span class="comment">// </foo> +</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">&</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"><<</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">// <?xml version="1.0"?><foo bar="baz"><call>hey</call></foo></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="comment">// raw output; prints +</span><span class="comment">// <?xml version="1.0"?><foo bar="baz"><call>hey</call></foo> +</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"><<</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">endl</span><span class="special">;</span> -<span class="comment">// raw output without declaration; prints</span> -<span class="comment">// <foo bar="baz"><call>hey</call></foo></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="comment">// raw output without declaration; prints +</span><span class="comment">// <foo bar="baz"><call>hey</call></foo> +</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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> </pre> <p> @@ -416,7 +419,7 @@ </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> +<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 @@ -424,7 +427,7 @@ 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 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> @@ -457,7 +460,7 @@ </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> +<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 @@ -490,22 +493,23 @@ 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</span><span class="special">(</span><span class="string">"<foo bar='baz'><call>hey</call></foo>"</span><span class="special">);</span> +<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">"<foo bar='baz'><call>hey</call></foo>"</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="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">// <?xml version="1.0" encoding="UTF-8" standalone="no"?> </span> -<span class="comment">// <foo bar="baz"></span> -<span class="comment">// <call>hey</call></span> -<span class="comment">// </foo></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="comment">// <?xml version="1.0" encoding="UTF-8" standalone="no"?> +</span><span class="comment">// <foo bar="baz"> +</span><span class="comment">// <call>hey</call> +</span><span class="comment">// </foo> +</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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> </pre> <p> @@ -522,7 +526,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: diff --git a/docs/manual/toc.html b/docs/manual/toc.html index 3bedd68..b36f757 100644 --- a/docs/manual/toc.html +++ b/docs/manual/toc.html @@ -4,14 +4,14 @@ <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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> <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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: @@ -27,112 +27,113 @@ <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> +<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> +<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> +<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> +<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> +<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.subversion">Subversion repository</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.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> +<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 +<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 +<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 +<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 +<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> +<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> +<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> +<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 +<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 +<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> +<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> +<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> +<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 +<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 +<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> +<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> +<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.fragments">Assembling document from fragments</a></span></dt> +<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> +<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> +<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> +<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> +<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> +<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> @@ -145,7 +146,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: diff --git a/docs/manual/xpath.html b/docs/manual/xpath.html index e2290e5..7194283 100644 --- a/docs/manual/xpath.html +++ b/docs/manual/xpath.html @@ -4,15 +4,15 @@ <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.4"> -<link rel="up" href="../manual.html" title="pugixml 1.4"> +<link rel="home" href="../manual.html" title="pugixml 1.5"> +<link rel="up" href="../manual.html" title="pugixml 1.5"> <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.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: @@ -28,15 +28,15 @@ <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> +<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> +<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 @@ -48,7 +48,7 @@ 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 + 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>, @@ -58,12 +58,11 @@ </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> +<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> -<p> - <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>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> +<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 @@ -73,11 +72,11 @@ <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> -<p> - <a name="xpath_node"></a><a name="xpath_node::node"></a><a name="xpath_node::attribute"></a><a name="xpath_node::parent"></a>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> +<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: @@ -102,33 +101,30 @@ handle. For null nodes, <code class="computeroutput"><span class="identifier">parent</span></code> returns null handle. </p> -<p> - <a name="xpath_node::unspecified_bool_type"></a><a name="xpath_node::comparison"></a>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 +<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> -<p> - <a name="xpath_node::ctor"></a>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> -<p> - <a name="xpath_node_set"></a>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> -<p> - <a name="xpath_node_set::const_iterator"></a><a name="xpath_node_set::begin"></a><a name="xpath_node_set::end"></a>Node sets are represented by <code class="computeroutput"><span class="identifier">xpath_node_set</span></code> +<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: @@ -137,9 +133,8 @@ <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> -<p> - <a name="xpath_node_set::index"></a><a name="xpath_node_set::size"></a><a name="xpath_node_set::empty"></a>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>: +<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">&</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> @@ -152,9 +147,9 @@ 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> -<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>The order of iteration depends on the order of - nodes inside the set; the order can be queried via the following function: +<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> @@ -178,10 +173,9 @@ 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> -<p> - <a name="xpath_node_set::first"></a>Often the actual iteration is not needed; - instead, only the first element in document order is required. For this, - a special accessor is provided: +<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> @@ -193,11 +187,10 @@ the complexity does - if the set is sorted, the complexity is constant, otherwise it is linear in the number of elements or worse. </p> -<p> - <a name="xpath_node_set::ctor"></a>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> +<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> @@ -212,41 +205,40 @@ </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> +<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> -<p> - <a name="xml_node::select_single_node"></a><a name="xml_node::select_nodes"></a>If - you want to select nodes that match some XPath expression, you can do it - with the following functions: +<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_single_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> +<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_single_node</span></code> + 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_single_node</span></code> - returns null XPath node. + 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. + than node set; see <a class="xref" href="xpath.html#manual.xpath.errors" title="Error handling"> Error handling</a> for details. </p> -<p> - <a name="xml_node::select_single_node_precomp"></a><a name="xml_node::select_nodes_precomp"></a>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: +<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_single_node</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">xpath_query</span><span class="special">&</span> <span class="identifier">query</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span> +<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">&</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">&</span> <span class="identifier">query</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span> </pre> <p> @@ -257,6 +249,7 @@ 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> @@ -268,7 +261,7 @@ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><<</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_single_node</span><span class="special">(</span><span class="string">"//Tool[contains(Description, 'build system')]"</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"><<</span> <span class="string">"Build tool: "</span> <span class="special"><<</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"><<</span> <span class="string">"\n"</span><span class="special">;</span> @@ -278,10 +271,10 @@ </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> +<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> -<p> - <a name="xpath_query"></a>When you call <code class="computeroutput"><span class="identifier">select_nodes</span></code> +<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: @@ -307,30 +300,29 @@ operator and store pointers to <code class="computeroutput"><span class="identifier">xpath_query</span></code> in the container. </p> -<p> - <a name="xpath_query::ctor"></a>You can create a query object with the constructor - that takes XPath expression as an argument: +<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> -<p> - <a name="xpath_query::return_type"></a>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: +<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> -<p> - <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>You - can evaluate the query using one of the following functions: +<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">&</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">&</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">&</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">&</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">&</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 @@ -339,8 +331,9 @@ 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> results - 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>). + 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> @@ -349,12 +342,12 @@ </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>. + 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> -<p> - <a name="xpath_query::evaluate_string_buffer"></a>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> +<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> @@ -386,20 +379,21 @@ 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> +<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"><<</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="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"><<</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"><<</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, '_')) > 0 and @OutputFileMasks"</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, '_')) > 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> @@ -414,7 +408,7 @@ </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> +<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 @@ -426,10 +420,10 @@ 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_single_node</span></code> functions: + 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_single_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</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> @@ -447,13 +441,12 @@ that the lifetime of the set exceeds that of query object. </p></td></tr> </table></div> -<p> - <a name="xpath_variable_set"></a>Variable sets correspond to <code class="computeroutput"><span class="identifier">xpath_variable_set</span></code> type, which is essentially - a variable container. +<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> -<p> - <a name="xpath_variable_set::add"></a>You can add new variables with the - following function: +<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> @@ -470,9 +463,8 @@ <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> -<p> - <a name="xpath_variable_set::get"></a>You can get the existing variables - with the following functions: +<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> @@ -481,14 +473,13 @@ The functions return the variable handle, or null pointer if the variable with the specified name is not found. </p> -<p> - <a name="xpath_variable_set::set"></a>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. +<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> @@ -499,15 +490,14 @@ The variable values are copied to the internal variable storage, so you can modify or destroy them after the functions return. </p> -<p> - <a name="xpath_variable"></a>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>. +<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> -<p> - <a name="xpath_variable::type"></a><a name="xpath_variable::name"></a>In - order to get variable information, you can use one of the following functions: +<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> @@ -516,9 +506,8 @@ Note that each variable has a distinct type which is specified upon variable creation and can not be changed later. </p> -<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>In - order to get variable value, you should use one of the following functions, +<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> @@ -531,9 +520,9 @@ 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> -<p> - <a name="xpath_variable::set"></a>In order to set variable value, you should - use one of the following functions, depending on the variable type: +<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> @@ -550,9 +539,10 @@ 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> +<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">&</span><span class="identifier">vars</span><span class="special">);</span> @@ -569,8 +559,8 @@ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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_single_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">&</span><span class="identifier">vars</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">&</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"><<</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> @@ -580,7 +570,7 @@ </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> +<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; @@ -588,23 +578,21 @@ is controlled with <a class="link" href="install.html#PUGIXML_NO_EXCEPTIONS">PUGIXML_NO_EXCEPTIONS</a> define). </p> -<p> - <a name="xpath_exception"></a><a name="xpath_exception::result"></a><a name="xpath_exception::what"></a>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: +<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">&</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> -<p> - <a name="xpath_query::unspecified_bool_type"></a><a name="xpath_query::result"></a>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> +<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: @@ -617,9 +605,8 @@ a query as a node set results in an empty node set if the return type is not node set. </p> -<p> - <a name="xpath_parse_result"></a>The information about parsing result is - returned via <code class="computeroutput"><span class="identifier">xpath_parse_result</span></code> +<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> @@ -632,39 +619,39 @@ <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> -<p> - <a name="xpath_parse_result::error"></a>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. +<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> -<p> - <a name="xpath_parse_result::description"></a><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 +<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> - 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. + 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> - <a name="xpath_parse_result::offset"></a>In addition to the error message, - parsing result has an <code class="computeroutput"><span class="identifier">offset</span></code> +<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> -<p> - <a name="xpath_parse_result::bool"></a>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> +<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> +<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> @@ -673,8 +660,8 @@ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Select failed: "</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special"><<</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="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> @@ -683,8 +670,8 @@ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Select failed: "</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special"><<</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="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> @@ -698,7 +685,7 @@ </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> +<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 @@ -745,7 +732,7 @@ <hr> <table width="100%"><tr> <td> -<a href="http://pugixml.org/">pugixml 1.4</a> manual | +<a href="http://pugixml.org/">pugixml 1.5</a> manual | <a href="../manual.html">Overview</a> | <a href="install.html">Installation</a> | Document: diff --git a/docs/quickstart.html b/docs/quickstart.html index 8f8fa4e..c702852 100644 --- a/docs/quickstart.html +++ b/docs/quickstart.html @@ -1,31 +1,31 @@ <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> -<title>pugixml 1.4</title> +<title>pugixml 1.5</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.4"> +<link rel="home" href="quickstart.html" title="pugixml 1.5"> </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.4 quick start guide">pugixml 1.4 quick start guide</a> +<a name="quickstart.main"></a><a class="link" href="quickstart.html#quickstart.main" title="pugixml 1.5 quick start guide"> pugixml 1.5 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> +<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> +<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 @@ -59,7 +59,7 @@ </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 + 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 @@ -69,14 +69,14 @@ </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> +<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.4/pugixml-1.4.zip" target="_top">https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.zip</a> -<a href="https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.tar.gz" target="_top">https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.tar.gz</a> +<pre class="programlisting"><a href="https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.zip" target="_top">https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.zip</a> +<a href="https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.tar.gz" target="_top">https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.tar.gz</a> </pre> <p> The distribution contains library source, documentation (the guide you're @@ -109,7 +109,7 @@ </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> +<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 @@ -226,7 +226,7 @@ </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> +<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 @@ -250,6 +250,7 @@ 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> @@ -281,9 +282,10 @@ 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</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">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"><<</span> <span class="string">"XML ["</span> <span class="special"><<</span> <span class="identifier">source</span> <span class="special"><<</span> <span class="string">"] parsed without errors, attr value: ["</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">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"><<</span> <span class="string">"]\n\n"</span><span class="special">;</span> @@ -322,6 +324,7 @@ 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">"<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>"</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> @@ -329,16 +332,17 @@ <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> +<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">// 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> +<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> @@ -348,6 +352,7 @@ 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> @@ -357,7 +362,7 @@ </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> +<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 @@ -394,6 +399,7 @@ 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> @@ -414,6 +420,7 @@ 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"><<</span> <span class="string">"Tool for *.dae generation: "</span> <span class="special"><<</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"><<</span> <span class="string">"\n"</span><span class="special">;</span> @@ -438,6 +445,7 @@ 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> @@ -466,6 +474,7 @@ (<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> @@ -499,22 +508,24 @@ 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">&</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"><</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"><<</span> <span class="string">" "</span><span class="special">;</span> <span class="comment">// indentation</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"><</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"><<</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"><<</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"><<</span> <span class="string">": name='"</span> <span class="special"><<</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">name</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"', value='"</span> <span class="special"><<</span> <span class="identifier">node</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special"><<</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="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> @@ -528,6 +539,7 @@ 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> @@ -539,7 +551,7 @@ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><<</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_single_node</span><span class="special">(</span><span class="string">"//Tool[contains(Description, 'build system')]"</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"><<</span> <span class="string">"Build tool: "</span> <span class="special"><<</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"><<</span> <span class="string">"\n"</span><span class="special">;</span> @@ -559,7 +571,7 @@ </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> +<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 @@ -590,36 +602,38 @@ 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"><<</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="comment">// change node name +</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><<</span> <span class="string">", new node name: "</span> <span class="special"><<</span> <span class="identifier">node</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">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"><<</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="comment">// change comment text +</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><<</span> <span class="string">", new comment text: "</span> <span class="special"><<</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"><<</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"><<</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"><<</span> <span class="string">", "</span> <span class="special"><<</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"><<</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"><<</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"><<</span> <span class="string">", "</span> <span class="special"><<</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"><<</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"><<</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"><<</span> <span class="string">", "</span> <span class="special"><<</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="comment">// change attribute name/value +</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</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"><<</span> <span class="string">", "</span> <span class="special"><<</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"><<</span> <span class="string">", new attribute: "</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="special"><<</span> <span class="string">"="</span> <span class="special"><<</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">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="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"><<</span> <span class="string">"new attribute value: "</span> <span class="special"><<</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">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="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"><<</span> <span class="string">"final attribute value: "</span> <span class="special"><<</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">endl</span><span class="special">;</span> </pre> <p> @@ -649,19 +663,20 @@ 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> +<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="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 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="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> @@ -681,17 +696,18 @@ 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> +<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="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="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> @@ -699,7 +715,7 @@ </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> +<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 @@ -724,9 +740,10 @@ 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"><<</span> <span class="string">"Saving result: "</span> <span class="special"><<</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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +<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"><<</span> <span class="string">"Saving result: "</span> <span class="special"><<</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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> </pre> <p> </p> @@ -743,9 +760,10 @@ 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"><<</span> <span class="string">"Document:\n"</span><span class="special">;</span> +<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"><<</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> @@ -765,6 +783,7 @@ 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> @@ -789,7 +808,7 @@ </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> +<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="http://code.google.com/p/pugixml/issues/entry" target="_top">issue submission form</a>. @@ -798,14 +817,14 @@ that uses pugixml and exhibits the bug, etc. Feature requests and contributions can be filed as issues, too. </p> -<p> - <a name="email"></a>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>. +<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> +<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: @@ -854,7 +873,7 @@ pugixml </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: February 28, 2014 at 03:52:54 GMT</small></p></td> +<td align="left"><p><small>Last revised: November 18, 2014 at 17:25:31 GMT</small></p></td> <td align="right"><div class="copyright-footer"></div></td> </tr></table> </body> diff --git a/docs/quickstart.qbk b/docs/quickstart.qbk index c913ccb..b609518 100644 --- a/docs/quickstart.qbk +++ b/docs/quickstart.qbk @@ -1,7 +1,7 @@ [article pugixml [quickbook 1.5] - [version 1.4] + [version 1.5] [id quickstart] [copyright 2014 Arseny Kapoulkine] [license Distributed under the MIT License] @@ -11,7 +11,7 @@ [template sref[name]'''<xref linkend="quickstart.main.'''[name]'''" xrefstyle="select:title" />'''] [template ftnt[id text]'''<footnote id="'''[id]'''"><para>'''[text]'''</para></footnote>'''] -[section:main pugixml 1.4 quick start guide] +[section:main pugixml 1.5 quick start guide] [section:introduction Introduction] @@ -30,8 +30,8 @@ This is the quick start guide for pugixml, which purpose is to enable you to sta pugixml is distributed in source form. You can download a source distribution via one of the following links: [pre -[@https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.zip] -[@https://github.com/zeux/pugixml/releases/download/v1.4/pugixml-1.4.tar.gz] +[@https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.zip] +[@https://github.com/zeux/pugixml/releases/download/v1.5/pugixml-1.5.tar.gz] ] 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 - [file .zip] archive has Windows line endings, [file .tar.gz] archive has Unix line endings. Otherwise the files in both archives are identical. @@ -219,7 +219,7 @@ While the previously described functions save the whole document to the destinat [section:feedback Feedback] -If you believe you've found a bug in pugixml, please file an issue via [@http://code.google.com/p/pugixml/issues/entry issue submission form]. 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. +If you believe you've found a bug in pugixml, please file an issue via [@https://github.com/zeux/pugixml/issues/new issue submission form]. 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. [#email] If filing an issue is not possible due to privacy or other concerns, you can contact pugixml author by e-mail directly: [@mailto:arseny.kapoulkine@gmail.com arseny.kapoulkine@gmail.com]. diff --git a/docs/samples/custom_memory_management.cpp b/docs/samples/custom_memory_management.cpp index 92ccb71..f11d27e 100644 --- a/docs/samples/custom_memory_management.cpp +++ b/docs/samples/custom_memory_management.cpp @@ -21,7 +21,7 @@ int main() //] pugi::xml_document doc; - doc.load("<node/>"); + doc.load_string("<node/>"); } // vim:et diff --git a/docs/samples/load_error_handling.cpp b/docs/samples/load_error_handling.cpp index 18dd331..8dceb99 100644 --- a/docs/samples/load_error_handling.cpp +++ b/docs/samples/load_error_handling.cpp @@ -6,7 +6,7 @@ void check_xml(const char* source) { //[code_load_error_handling pugi::xml_document doc; - pugi::xml_parse_result result = doc.load(source); + pugi::xml_parse_result result = doc.load_string(source); if (result) std::cout << "XML [" << source << "] parsed without errors, attr value: [" << doc.child("node").attribute("attr").value() << "]\n\n"; diff --git a/docs/samples/load_memory.cpp b/docs/samples/load_memory.cpp index 1185944..490f7e4 100644 --- a/docs/samples/load_memory.cpp +++ b/docs/samples/load_memory.cpp @@ -55,7 +55,7 @@ int main() { //[code_load_memory_string // You can use load to load document from null-terminated strings, for example literals: - pugi::xml_parse_result result = doc.load("<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>"); + pugi::xml_parse_result result = doc.load_string("<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>"); //] std::cout << "Load result: " << result.description() << ", mesh name: " << doc.child("mesh").attribute("name").value() << std::endl; diff --git a/docs/samples/load_options.cpp b/docs/samples/load_options.cpp index 04b4b46..2589348 100644 --- a/docs/samples/load_options.cpp +++ b/docs/samples/load_options.cpp @@ -10,19 +10,19 @@ int main() const char* source = "<!--comment--><node><</node>"; // Parsing with default options; note that comment node is not added to the tree, and entity reference < is expanded - doc.load(source); + doc.load_string(source); std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n"; // Parsing with additional parse_comments option; comment node is now added to the tree - doc.load(source, pugi::parse_default | pugi::parse_comments); + doc.load_string(source, pugi::parse_default | pugi::parse_comments); std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n"; // Parsing with additional parse_comments option and without the (default) parse_escapes option; < is not expanded - doc.load(source, (pugi::parse_default | pugi::parse_comments) & ~pugi::parse_escapes); + doc.load_string(source, (pugi::parse_default | pugi::parse_comments) & ~pugi::parse_escapes); std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n"; // Parsing with minimal option mask; comment node is not added to the tree, and < is not expanded - doc.load(source, pugi::parse_minimal); + doc.load_string(source, pugi::parse_minimal); std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n"; //] } diff --git a/docs/samples/modify_base.cpp b/docs/samples/modify_base.cpp index 7d0959a..bd63708 100644 --- a/docs/samples/modify_base.cpp +++ b/docs/samples/modify_base.cpp @@ -6,7 +6,7 @@ int main() { pugi::xml_document doc; - if (!doc.load("<node id='123'>text</node><!-- comment -->", pugi::parse_default | pugi::parse_comments)) return -1; + if (!doc.load_string("<node id='123'>text</node><!-- comment -->", pugi::parse_default | pugi::parse_comments)) return -1; //[code_modify_base_node pugi::xml_node node = doc.child("node"); diff --git a/docs/samples/modify_remove.cpp b/docs/samples/modify_remove.cpp index 28c2f6b..53020e1 100644 --- a/docs/samples/modify_remove.cpp +++ b/docs/samples/modify_remove.cpp @@ -5,7 +5,7 @@ int main() { pugi::xml_document doc; - if (!doc.load("<node><description>Simple node</description><param name='id' value='123'/></node>")) return -1; + if (!doc.load_string("<node><description>Simple node</description><param name='id' value='123'/></node>")) return -1; //[code_modify_remove // remove description node with the whole subtree diff --git a/docs/samples/save_custom_writer.cpp b/docs/samples/save_custom_writer.cpp index 6ea4300..fe08b72 100644 --- a/docs/samples/save_custom_writer.cpp +++ b/docs/samples/save_custom_writer.cpp @@ -11,7 +11,7 @@ struct xml_string_writer: pugi::xml_writer virtual void write(const void* data, size_t size) { - result += std::string(static_cast<const char*>(data), size); + result.append(static_cast<const char*>(data), size); } }; //] @@ -94,7 +94,7 @@ int main() { // get a test document pugi::xml_document doc; - doc.load("<foo bar='baz'>hey</foo>"); + doc.load_string("<foo bar='baz'>hey</foo>"); // get contents as std::string (single pass) std::cout << "contents: [" << node_to_string(doc) << "]\n"; diff --git a/docs/samples/save_declaration.cpp b/docs/samples/save_declaration.cpp index 6c82061..a45831f 100644 --- a/docs/samples/save_declaration.cpp +++ b/docs/samples/save_declaration.cpp @@ -7,7 +7,7 @@ int main() //[code_save_declaration
// get a test document
pugi::xml_document doc;
- doc.load("<foo bar='baz'><call>hey</call></foo>");
+ doc.load_string("<foo bar='baz'><call>hey</call></foo>");
// add a custom declaration node
pugi::xml_node decl = doc.prepend_child(pugi::node_declaration);
diff --git a/docs/samples/save_file.cpp b/docs/samples/save_file.cpp index 30c1aa1..21413a2 100644 --- a/docs/samples/save_file.cpp +++ b/docs/samples/save_file.cpp @@ -6,7 +6,7 @@ int main() { // get a test document pugi::xml_document doc; - doc.load("<foo bar='baz'>hey</foo>"); + doc.load_string("<foo bar='baz'>hey</foo>"); //[code_save_file // save document to file diff --git a/docs/samples/save_options.cpp b/docs/samples/save_options.cpp index 6a49f66..82abdcd 100644 --- a/docs/samples/save_options.cpp +++ b/docs/samples/save_options.cpp @@ -7,7 +7,7 @@ int main() //[code_save_options // get a test document pugi::xml_document doc; - doc.load("<foo bar='baz'><call>hey</call></foo>"); + doc.load_string("<foo bar='baz'><call>hey</call></foo>"); // default options; prints // <?xml version="1.0"?> diff --git a/docs/samples/save_stream.cpp b/docs/samples/save_stream.cpp index d01965d..eba1863 100644 --- a/docs/samples/save_stream.cpp +++ b/docs/samples/save_stream.cpp @@ -6,7 +6,7 @@ int main() { // get a test document pugi::xml_document doc; - doc.load("<foo bar='baz'><call>hey</call></foo>"); + doc.load_string("<foo bar='baz'><call>hey</call></foo>"); //[code_save_stream // save document to standard output diff --git a/docs/samples/save_subtree.cpp b/docs/samples/save_subtree.cpp index 0091b3d..a94e10a 100644 --- a/docs/samples/save_subtree.cpp +++ b/docs/samples/save_subtree.cpp @@ -7,7 +7,7 @@ int main() //[code_save_subtree // get a test document pugi::xml_document doc; - doc.load("<foo bar='baz'><call>hey</call></foo>"); + doc.load_string("<foo bar='baz'><call>hey</call></foo>"); // print document to standard output (prints <?xml version="1.0"?><foo bar="baz"><call>hey</call></foo>) doc.save(std::cout, "", pugi::format_raw); diff --git a/docs/samples/text.cpp b/docs/samples/text.cpp index 9b1cf69..a0d591b 100644 --- a/docs/samples/text.cpp +++ b/docs/samples/text.cpp @@ -7,7 +7,7 @@ int main() pugi::xml_document doc;
// get a test document
- doc.load("<project><name>test</name><version>1.1</version><public>yes</public></project>");
+ doc.load_string("<project><name>test</name><version>1.1</version><public>yes</public></project>");
pugi::xml_node project = doc.child("project");
@@ -1,4 +1,4 @@ -pugixml 1.4 - an XML processing library +pugixml 1.5 - an XML processing library Copyright (C) 2006-2014, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) Report bugs and download new versions at http://pugixml.org/ diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index bd33220..daf6b35 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -22,7 +22,7 @@ else() add_library(pugixml STATIC ${SOURCES}) endif() -set_target_properties(pugixml PROPERTIES VERSION 1.4 SOVERSION 1) +set_target_properties(pugixml PROPERTIES VERSION 1.5 SOVERSION 1) install(TARGETS pugixml EXPORT pugixml-config ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/src/pugiconfig.hpp b/src/pugiconfig.hpp index 56f1d22..6219dbe 100644 --- a/src/pugiconfig.hpp +++ b/src/pugiconfig.hpp @@ -1,5 +1,5 @@ /** - * pugixml parser - version 1.4 + * pugixml parser - version 1.5 * -------------------------------------------------------- * Copyright (C) 2006-2014, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ @@ -39,7 +39,6 @@ // Uncomment this to switch to header-only version // #define PUGIXML_HEADER_ONLY -// #include "pugixml.cpp" // Uncomment this to enable long long support // #define PUGIXML_HAS_LONG_LONG diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 1d390eb..787f693 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -1,6 +1,5 @@ /** -{ - * pugixml parser - version 1.4 + * pugixml parser - version 1.5 * -------------------------------------------------------- * Copyright (C) 2006-2014, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ @@ -286,8 +285,6 @@ PUGI__NS_BEGIN { static xml_memory_page* construct(void* memory) { - if (!memory) return 0; //$ redundant, left for performance - xml_memory_page* result = static_cast<xml_memory_page*>(memory); result->allocator = 0; @@ -328,7 +325,7 @@ PUGI__NS_BEGIN void* memory = xml_memory::allocate(size + xml_memory_page_alignment); if (!memory) return 0; - // align upwards to page boundary (note: this guarantees at least 1 usable byte before the page) + // align to next page boundary (note: this guarantees at least 1 usable byte before the page) char* page_memory = reinterpret_cast<char*>((reinterpret_cast<uintptr_t>(memory) + xml_memory_page_alignment) & ~(xml_memory_page_alignment - 1)); // prepare page structure @@ -338,6 +335,7 @@ PUGI__NS_BEGIN page->allocator = _root->allocator; // record the offset for freeing the memory block + assert(page_memory > memory && page_memory - static_cast<char*>(memory) <= 127); page_memory[-1] = static_cast<char>(page_memory - static_cast<char*>(memory)); return page; @@ -402,6 +400,8 @@ PUGI__NS_BEGIN char_t* allocate_string(size_t length) { + PUGI__STATIC_ASSERT(xml_memory_page_size <= (1 << 16)); + // allocate memory for string and header block size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t); @@ -711,6 +711,7 @@ PUGI__NS_BEGIN else parent->first_child = node->next_sibling; + node->parent = 0; node->prev_sibling_c = 0; node->next_sibling = 0; } @@ -2356,23 +2357,28 @@ PUGI__NS_BEGIN char_t* parse_doctype_ignore(char_t* s) { + size_t depth = 0; + assert(s[0] == '<' && s[1] == '!' && s[2] == '['); - s++; + s += 3; while (*s) { if (s[0] == '<' && s[1] == '!' && s[2] == '[') { // nested ignore section - s = parse_doctype_ignore(s); - if (!s) return s; + s += 3; + depth++; } else if (s[0] == ']' && s[1] == ']' && s[2] == '>') { // ignore section end s += 3; - return s; + if (depth == 0) + return s; + + depth--; } else s++; } @@ -2380,10 +2386,12 @@ PUGI__NS_BEGIN PUGI__THROW_ERROR(status_bad_doctype, s); } - char_t* parse_doctype_group(char_t* s, char_t endch, bool toplevel) + char_t* parse_doctype_group(char_t* s, char_t endch) { + size_t depth = 0; + assert((s[0] == '<' || s[0] == 0) && s[1] == '!'); - s++; + s += 2; while (*s) { @@ -2398,12 +2406,8 @@ PUGI__NS_BEGIN else { // some control group - s = parse_doctype_group(s, endch, false); - if (!s) return s; - - // skip > - assert(*s == '>'); - s++; + s += 2; + depth++; } } else if (s[0] == '<' || s[0] == '"' || s[0] == '\'') @@ -2414,12 +2418,16 @@ PUGI__NS_BEGIN } else if (*s == '>') { - return s; + if (depth == 0) + return s; + + depth--; + s++; } else s++; } - if (!toplevel || endch != '>') PUGI__THROW_ERROR(status_bad_doctype, s); + if (depth != 0 || endch != '>') PUGI__THROW_ERROR(status_bad_doctype, s); return s; } @@ -2511,7 +2519,7 @@ PUGI__NS_BEGIN char_t* mark = s + 9; - s = parse_doctype_group(s, endch, true); + s = parse_doctype_group(s, endch); if (!s) return s; assert((*s == 0 && endch == '>') || *s == '>'); @@ -2670,15 +2678,11 @@ PUGI__NS_BEGIN a->name = s; // Save the offset. PUGI__SCANWHILE_UNROLL(PUGI__IS_CHARTYPE(ss, ct_symbol)); // Scan for a terminator. - PUGI__CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance - PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. - PUGI__CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance if (PUGI__IS_CHARTYPE(ch, ct_space)) { PUGI__SKIPWS(); // Eat any whitespace. - PUGI__CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance ch = *s; ++s; @@ -3647,11 +3651,12 @@ PUGI__NS_BEGIN } node = node->parent; - depth--; // write closing node if (PUGI__NODETYPE(node) == node_element) { + depth--; + if (indent_length) text_output_indent(writer, indent, indent_length, depth); @@ -3662,11 +3667,11 @@ PUGI__NS_BEGIN while (node != root); } - PUGI__FN bool has_declaration(xml_node node) + PUGI__FN bool has_declaration(xml_node_struct* node) { - for (xml_node child = node.first_child(); child; child = child.next_sibling()) + for (xml_node_struct* child = node->first_child; child; child = child->next_sibling) { - xml_node_type type = child.type(); + xml_node_type type = PUGI__NODETYPE(child); if (type == node_declaration) return true; if (type == node_element) return false; @@ -3684,6 +3689,11 @@ PUGI__NS_BEGIN return false; } + PUGI__FN bool allow_insert_attribute(xml_node_type parent) + { + return parent == node_element || parent == node_declaration; + } + PUGI__FN bool allow_insert_child(xml_node_type parent, xml_node_type child) { if (parent != node_document && parent != node_element) return false; @@ -3719,6 +3729,8 @@ PUGI__NS_BEGIN PUGI__FN void node_copy_string(char_t*& dest, uintptr_t& header, uintptr_t header_mask, char_t* source, uintptr_t& source_header, xml_allocator* alloc) { + assert(!dest && (header & header_mask) == 0); + if (source) { if (alloc && (source_header & header_mask) == 0) @@ -3949,10 +3961,18 @@ PUGI__NS_BEGIN return set_value_buffer(dest, header, header_mask, buf); } + PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, float value) + { + char buf[128]; + sprintf(buf, "%.9g", value); + + return set_value_buffer(dest, header, header_mask, buf); + } + PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, double value) { char buf[128]; - sprintf(buf, "%g", value); + sprintf(buf, "%.17g", value); return set_value_buffer(dest, header, header_mask, buf); } @@ -3990,7 +4010,7 @@ PUGI__NS_BEGIN _fseeki64(file, 0, SEEK_END); length_type length = _ftelli64(file); _fseeki64(file, 0, SEEK_SET); - #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && !defined(__STRICT_ANSI__) + #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR)) // there are 64-bit versions of fseek/ftell, let's use them typedef off64_t length_type; @@ -4235,7 +4255,7 @@ PUGI__NS_BEGIN } #endif -#if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && !defined(__STRICT_ANSI__)) +#if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR))) PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) { return _wfopen(path, mode); @@ -4545,6 +4565,12 @@ namespace pugi return *this; } + PUGI__FN xml_attribute& xml_attribute::operator=(float rhs) + { + set_value(rhs); + return *this; + } + PUGI__FN xml_attribute& xml_attribute::operator=(bool rhs) { set_value(rhs); @@ -4600,6 +4626,13 @@ namespace pugi return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } + PUGI__FN bool xml_attribute::set_value(float rhs) + { + if (!_attr) return false; + + return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + } + PUGI__FN bool xml_attribute::set_value(bool rhs) { if (!_attr) return false; @@ -4803,11 +4836,7 @@ namespace pugi PUGI__FN xml_node xml_node::root() const { - if (!_root) return xml_node(); - - impl::xml_memory_page* page = reinterpret_cast<impl::xml_memory_page*>(_root->header & impl::xml_memory_page_pointer_mask); - - return xml_node(static_cast<impl::xml_document_struct*>(page->allocator)); + return _root ? xml_node(&impl::get_document(_root)) : xml_node(); } PUGI__FN xml_text xml_node::text() const @@ -4883,7 +4912,7 @@ namespace pugi PUGI__FN xml_attribute xml_node::append_attribute(const char_t* name_) { - if (type() != node_element && type() != node_declaration) return xml_attribute(); + if (!impl::allow_insert_attribute(type())) return xml_attribute(); xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); if (!a) return xml_attribute(); @@ -4897,7 +4926,7 @@ namespace pugi PUGI__FN xml_attribute xml_node::prepend_attribute(const char_t* name_) { - if (type() != node_element && type() != node_declaration) return xml_attribute(); + if (!impl::allow_insert_attribute(type())) return xml_attribute(); xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); if (!a) return xml_attribute(); @@ -4911,7 +4940,7 @@ namespace pugi PUGI__FN xml_attribute xml_node::insert_attribute_after(const char_t* name_, const xml_attribute& attr) { - if (type() != node_element && type() != node_declaration) return xml_attribute(); + if (!impl::allow_insert_attribute(type())) return xml_attribute(); if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); @@ -4926,7 +4955,7 @@ namespace pugi PUGI__FN xml_attribute xml_node::insert_attribute_before(const char_t* name_, const xml_attribute& attr) { - if (type() != node_element && type() != node_declaration) return xml_attribute(); + if (!impl::allow_insert_attribute(type())) return xml_attribute(); if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root))); @@ -4981,7 +5010,7 @@ namespace pugi PUGI__FN xml_node xml_node::append_child(xml_node_type type_) { - if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); @@ -4995,7 +5024,7 @@ namespace pugi PUGI__FN xml_node xml_node::prepend_child(xml_node_type type_) { - if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); @@ -5009,7 +5038,7 @@ namespace pugi PUGI__FN xml_node xml_node::insert_child_before(xml_node_type type_, const xml_node& node) { - if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); if (!node._root || node._root->parent != _root) return xml_node(); xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); @@ -5024,7 +5053,7 @@ namespace pugi PUGI__FN xml_node xml_node::insert_child_after(xml_node_type type_, const xml_node& node) { - if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); if (!node._root || node._root->parent != _root) return xml_node(); xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); @@ -5075,38 +5104,60 @@ namespace pugi PUGI__FN xml_node xml_node::append_copy(const xml_node& proto) { - xml_node result = append_child(proto.type()); + xml_node_type type_ = proto.type(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); - if (result) impl::node_copy_tree(result.internal_object(), proto.internal_object()); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); - return result; + impl::append_node(n._root, _root); + impl::node_copy_tree(n._root, proto._root); + + return n; } PUGI__FN xml_node xml_node::prepend_copy(const xml_node& proto) { - xml_node result = prepend_child(proto.type()); + xml_node_type type_ = proto.type(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); - if (result) impl::node_copy_tree(result.internal_object(), proto.internal_object()); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); - return result; + impl::prepend_node(n._root, _root); + impl::node_copy_tree(n._root, proto._root); + + return n; } PUGI__FN xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node) { - xml_node result = insert_child_after(proto.type(), node); + xml_node_type type_ = proto.type(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); + if (!node._root || node._root->parent != _root) return xml_node(); - if (result) impl::node_copy_tree(result.internal_object(), proto.internal_object()); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); - return result; + impl::insert_node_after(n._root, node._root); + impl::node_copy_tree(n._root, proto._root); + + return n; } PUGI__FN xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node) { - xml_node result = insert_child_before(proto.type(), node); + xml_node_type type_ = proto.type(); + if (!impl::allow_insert_child(type(), type_)) return xml_node(); + if (!node._root || node._root->parent != _root) return xml_node(); - if (result) impl::node_copy_tree(result.internal_object(), proto.internal_object()); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); - return result; + impl::insert_node_before(n._root, node._root); + impl::node_copy_tree(n._root, proto._root); + + return n; } PUGI__FN xml_node xml_node::append_move(const xml_node& moved) @@ -5202,8 +5253,7 @@ namespace pugi if (!impl::allow_insert_child(type(), node_element)) return impl::make_parse_result(status_append_invalid_root); // get document node - impl::xml_document_struct* doc = static_cast<impl::xml_document_struct*>(root()._root); - assert(doc); + impl::xml_document_struct* doc = &impl::get_document(_root); // disable document_buffer_order optimization since in a document with multiple buffers comparing buffer pointers does not make sense doc->header |= impl::xml_memory_page_contents_shared_mask; @@ -5414,13 +5464,12 @@ namespace pugi PUGI__FN ptrdiff_t xml_node::offset_debug() const { - xml_node_struct* r = root()._root; + if (!_root) return -1; - if (!r) return -1; + impl::xml_document_struct& doc = impl::get_document(_root); - const char_t* buffer = static_cast<impl::xml_document_struct*>(r)->buffer; - - if (!buffer) return -1; + // we can determine the offset reliably only if there is exactly once parse buffer + if (!doc.buffer || doc.extra_buffers) return -1; switch (type()) { @@ -5430,13 +5479,13 @@ namespace pugi case node_element: case node_declaration: case node_pi: - return (_root->header & impl::xml_memory_page_name_allocated_or_shared_mask) ? -1 : _root->name - buffer; + return _root->name && (_root->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0 ? _root->name - doc.buffer : -1; case node_pcdata: case node_cdata: case node_comment: case node_doctype: - return (_root->header & impl::xml_memory_page_value_allocated_or_shared_mask) ? -1 : _root->value - buffer; + return _root->value && (_root->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0 ? _root->value - doc.buffer : -1; default: return -1; @@ -5587,6 +5636,13 @@ namespace pugi return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } + PUGI__FN bool xml_text::set(float rhs) + { + xml_node_struct* dn = _data_new(); + + return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + } + PUGI__FN bool xml_text::set(double rhs) { xml_node_struct* dn = _data_new(); @@ -5641,6 +5697,12 @@ namespace pugi return *this; } + PUGI__FN xml_text& xml_text::operator=(float rhs) + { + set(rhs); + return *this; + } + PUGI__FN xml_text& xml_text::operator=(bool rhs) { set(rhs); @@ -5981,6 +6043,7 @@ namespace pugi // destroy dynamic storage, leave sentinel page (it's in static memory) impl::xml_memory_page* root_page = reinterpret_cast<impl::xml_memory_page*>(_root->header & impl::xml_memory_page_pointer_mask); assert(root_page && !root_page->prev); + assert(reinterpret_cast<char*>(root_page) >= _memory && reinterpret_cast<char*>(root_page) < _memory + sizeof(_memory)); for (impl::xml_memory_page* page = root_page->next; page; ) { @@ -6010,7 +6073,7 @@ namespace pugi } #endif - PUGI__FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options) + PUGI__FN xml_parse_result xml_document::load_string(const char_t* contents, unsigned int options) { // Force native encoding (skip autodetection) #ifdef PUGIXML_WCHAR_MODE @@ -6022,6 +6085,11 @@ namespace pugi return load_buffer(contents, impl::strlength(contents) * sizeof(char_t), options, encoding); } + PUGI__FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options) + { + return load_string(contents, options); + } + PUGI__FN xml_parse_result xml_document::load_file(const char* path_, unsigned int options, xml_encoding encoding) { reset(); @@ -6076,7 +6144,7 @@ namespace pugi #endif } - if (!(flags & format_no_declaration) && !impl::has_declaration(*this)) + if (!(flags & format_no_declaration) && !impl::has_declaration(_root)) { buffered_writer.write_string(PUGIXML_TEXT("<?xml version=\"1.0\"")); if (encoding == encoding_latin1) buffered_writer.write_string(PUGIXML_TEXT(" encoding=\"ISO-8859-1\"")); @@ -7384,7 +7452,7 @@ PUGI__NS_BEGIN return node.attribute() ? namespace_uri(node.attribute(), node.parent()) : namespace_uri(node.node()); } - PUGI__FN void normalize_space(char_t* buffer) + PUGI__FN char_t* normalize_space(char_t* buffer) { char_t* write = buffer; @@ -7408,9 +7476,11 @@ PUGI__NS_BEGIN // zero-terminate *write = 0; + + return write; } - PUGI__FN void translate(char_t* buffer, const char_t* from, const char_t* to, size_t to_length) + PUGI__FN char_t* translate(char_t* buffer, const char_t* from, const char_t* to, size_t to_length) { char_t* write = buffer; @@ -7428,6 +7498,8 @@ PUGI__NS_BEGIN // zero-terminate *write = 0; + + return write; } PUGI__FN unsigned char* translate_table_generate(xpath_allocator* alloc, const char_t* from, const char_t* to) @@ -7442,6 +7514,7 @@ PUGI__NS_BEGIN if (fc >= 128 || tc >= 128) return 0; + // code=128 means "skip character" if (!table[fc]) table[fc] = static_cast<unsigned char>(tc ? tc : 128); @@ -7463,7 +7536,7 @@ PUGI__NS_BEGIN return static_cast<unsigned char*>(result); } - PUGI__FN void translate_table(char_t* buffer, const unsigned char* table) + PUGI__FN char_t* translate_table(char_t* buffer, const unsigned char* table) { char_t* write = buffer; @@ -7476,6 +7549,8 @@ PUGI__NS_BEGIN { unsigned char code = table[index]; + // code=128 means "skip character" (table size is 128 so 128 can be a special value) + // this code skips these characters without extra branches *write = static_cast<char_t>(code); write += 1 - (code >> 7); } @@ -7487,6 +7562,8 @@ PUGI__NS_BEGIN // zero-terminate *write = 0; + + return write; } inline bool is_xpath_attribute(const char_t* name) @@ -7749,26 +7826,14 @@ PUGI__NS_BEGIN return xpath_first(_begin, _end, _type); } + void push_back_grow(const xpath_node& node, xpath_allocator* alloc); + void push_back(const xpath_node& node, xpath_allocator* alloc) { - if (_end == _eos) - { - size_t capacity = static_cast<size_t>(_eos - _begin); - - // get new capacity (1.5x rule) - size_t new_capacity = capacity + capacity / 2 + 1; - - // reallocate the old array or allocate a new one - xpath_node* data = static_cast<xpath_node*>(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node))); - assert(data); - - // finalize - _begin = data; - _end = data + capacity; - _eos = data + new_capacity; - } - - *_end++ = node; + if (_end != _eos) + *_end++ = node; + else + push_back_grow(node, alloc); } void append(const xpath_node* begin_, const xpath_node* end_, xpath_allocator* alloc) @@ -7825,6 +7890,26 @@ PUGI__NS_BEGIN _type = value; } }; + + PUGI__FN_NO_INLINE void xpath_node_set_raw::push_back_grow(const xpath_node& node, xpath_allocator* alloc) + { + size_t capacity = static_cast<size_t>(_eos - _begin); + + // get new capacity (1.5x rule) + size_t new_capacity = capacity + capacity / 2 + 1; + + // reallocate the old array or allocate a new one + xpath_node* data = static_cast<xpath_node*>(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node))); + assert(data); + + // finalize + _begin = data; + _end = data + capacity; + _eos = data + new_capacity; + + // push + *_end++ = node; + } PUGI__NS_END PUGI__NS_BEGIN @@ -8432,9 +8517,9 @@ PUGI__NS_BEGIN return false; } - static bool eval_once(bool forward, nodeset_eval_t eval) + static bool eval_once(xpath_node_set::type_t type, nodeset_eval_t eval) { - return forward ? eval != nodeset_eval_all : eval == nodeset_eval_any; + return type == xpath_node_set::type_sorted ? eval != nodeset_eval_all : eval == nodeset_eval_any; } template <class Comp> static bool compare_rel(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp) @@ -8606,7 +8691,7 @@ PUGI__NS_BEGIN { if (ns.size() == first) return; - bool last_once = eval_once(ns.type() == xpath_node_set::type_sorted, eval); + bool last_once = eval_once(ns.type(), eval); for (xpath_ast_node* pred = _right; pred; pred = pred->_next) pred->apply_predicate(ns, first, stack, !pred->_next && last_once); @@ -8614,7 +8699,7 @@ PUGI__NS_BEGIN bool step_push(xpath_node_set_raw& ns, xml_attribute_struct* a, xml_node_struct* parent, xpath_allocator* alloc) { - assert(a); + assert(a); const char_t* name = a->name ? a->name : PUGIXML_TEXT(""); @@ -8654,7 +8739,7 @@ PUGI__NS_BEGIN bool step_push(xpath_node_set_raw& ns, xml_node_struct* n, xpath_allocator* alloc) { - assert(n); + assert(n); xml_node_type type = PUGI__NODETYPE(n); @@ -9004,7 +9089,7 @@ PUGI__NS_BEGIN template <class T> void step_fill(xpath_node_set_raw& ns, const xpath_node& xn, xpath_allocator* alloc, bool once, T v) { const axis_t axis = T::axis; - bool axis_has_attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); + const bool axis_has_attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); if (xn.node()) step_fill(ns, xn.node().internal_object(), alloc, once, v); @@ -9015,15 +9100,16 @@ PUGI__NS_BEGIN template <class T> xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, nodeset_eval_t eval, T v) { const axis_t axis = T::axis; - bool axis_reverse = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling); + const bool axis_reverse = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling); + const xpath_node_set::type_t axis_type = axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; bool once = (axis == axis_attribute && _test == nodetest_name) || - (!_right && eval_once(!axis_reverse, eval)) || + (!_right && eval_once(axis_type, eval)) || (_right && !_right->_next && _right->_test == predicate_constant_one); xpath_node_set_raw ns; - ns.set_type(axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted); + ns.set_type(axis_type); if (_left) { @@ -9040,13 +9126,13 @@ PUGI__NS_BEGIN if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); step_fill(ns, *it, stack.result, once, v); - apply_predicates(ns, size, stack, eval); + if (_right) apply_predicates(ns, size, stack, eval); } } else { step_fill(ns, c.n, stack.result, once, v); - apply_predicates(ns, 0, stack, eval); + if (_right) apply_predicates(ns, 0, stack, eval); } // child, attribute and self axes always generate unique set of nodes @@ -9524,9 +9610,10 @@ PUGI__NS_BEGIN const char_t* pos = find_substring(s.c_str(), p.c_str()); if (!pos) return xpath_string(); - const char_t* result = pos + p.length(); + const char_t* rbegin = pos + p.length(); + const char_t* rend = s.c_str() + s.length(); - return s.uses_heap() ? xpath_string::from_heap(result, s.c_str() + s.length(), stack.result) : xpath_string::from_const(result); + return s.uses_heap() ? xpath_string::from_heap(rbegin, rend, stack.result) : xpath_string::from_const(rbegin); } case ast_func_substring_2: @@ -9547,8 +9634,9 @@ PUGI__NS_BEGIN assert(1 <= pos && pos <= s_length + 1); const char_t* rbegin = s.c_str() + (pos - 1); + const char_t* rend = s.c_str() + s.length(); - return s.uses_heap() ? xpath_string::from_heap(rbegin, s.c_str() + s.length(), stack.result) : xpath_string::from_const(rbegin); + return s.uses_heap() ? xpath_string::from_heap(rbegin, rend, stack.result) : xpath_string::from_const(rbegin); } case ast_func_substring_3: @@ -9582,18 +9670,20 @@ PUGI__NS_BEGIN { xpath_string s = string_value(c.n, stack.result); - normalize_space(s.data(stack.result)); + char_t* begin = s.data(stack.result); + char_t* end = normalize_space(begin); - return s; + return xpath_string::from_heap_preallocated(begin, end); } case ast_func_normalize_space_1: { xpath_string s = _left->eval_string(c, stack); - normalize_space(s.data(stack.result)); + char_t* begin = s.data(stack.result); + char_t* end = normalize_space(begin); - return s; + return xpath_string::from_heap_preallocated(begin, end); } case ast_func_translate: @@ -9606,18 +9696,20 @@ PUGI__NS_BEGIN xpath_string from = _right->eval_string(c, swapped_stack); xpath_string to = _right->_next->eval_string(c, swapped_stack); - translate(s.data(stack.result), from.c_str(), to.c_str(), to.length()); + char_t* begin = s.data(stack.result); + char_t* end = translate(begin, from.c_str(), to.c_str(), to.length()); - return s; + return xpath_string::from_heap_preallocated(begin, end); } case ast_opt_translate_table: { xpath_string s = _left->eval_string(c, stack); - translate_table(s.data(stack.result), _data.table); + char_t* begin = s.data(stack.result); + char_t* end = translate_table(begin, _data.table); - return s; + return xpath_string::from_heap_preallocated(begin, end); } case ast_variable: @@ -9687,7 +9779,7 @@ PUGI__NS_BEGIN // either expression is a number or it contains position() call; sort by document order if (_test != predicate_posinv) set.sort_do(); - bool once = eval_once(set.type() == xpath_node_set::type_sorted, eval); + bool once = eval_once(set.type(), eval); apply_predicate(set, 0, stack, once); diff --git a/src/pugixml.hpp b/src/pugixml.hpp index e252e16..9798b46 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -1,5 +1,5 @@ /** - * pugixml parser - version 1.4 + * pugixml parser - version 1.5 * -------------------------------------------------------- * Copyright (C) 2006-2014, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ @@ -13,7 +13,7 @@ #ifndef PUGIXML_VERSION // Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons -# define PUGIXML_VERSION 140 +# define PUGIXML_VERSION 150 #endif // Include user configuration file (this can define various configuration macros) @@ -352,6 +352,7 @@ namespace pugi bool set_value(int rhs); bool set_value(unsigned int rhs); bool set_value(double rhs); + bool set_value(float rhs); bool set_value(bool rhs); #ifdef PUGIXML_HAS_LONG_LONG @@ -364,6 +365,7 @@ namespace pugi xml_attribute& operator=(int rhs); xml_attribute& operator=(unsigned int rhs); xml_attribute& operator=(double rhs); + xml_attribute& operator=(float rhs); xml_attribute& operator=(bool rhs); #ifdef PUGIXML_HAS_LONG_LONG @@ -431,7 +433,7 @@ namespace pugi const char_t* name() const; // Get node value, or "" if node is empty or it has no value - // Note: For <node>text</node> node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes. + // Note: For <node>text</node> node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes. const char_t* value() const; // Get attribute list @@ -694,6 +696,7 @@ namespace pugi bool set(int rhs); bool set(unsigned int rhs); bool set(double rhs); + bool set(float rhs); bool set(bool rhs); #ifdef PUGIXML_HAS_LONG_LONG @@ -706,6 +709,7 @@ namespace pugi xml_text& operator=(int rhs); xml_text& operator=(unsigned int rhs); xml_text& operator=(double rhs); + xml_text& operator=(float rhs); xml_text& operator=(bool rhs); #ifdef PUGIXML_HAS_LONG_LONG @@ -959,9 +963,12 @@ namespace pugi xml_parse_result load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options = parse_default); #endif - // Load document from zero-terminated string. No encoding conversions are applied. + // (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied. xml_parse_result load(const char_t* contents, unsigned int options = parse_default); + // Load document from zero-terminated string. No encoding conversions are applied. + xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default); + // Load document from file xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); @@ -1326,6 +1333,13 @@ namespace std #endif +// Make sure implementation is included in header-only mode +// Use macro expansion in #include to work around QMake (QTBUG-11923) +#if defined(PUGIXML_HEADER_ONLY) && !defined(PUGIXML_SOURCE) +# define PUGIXML_SOURCE "pugixml.cpp" +# include PUGIXML_SOURCE +#endif + /** * Copyright (c) 2006-2014 Arseny Kapoulkine * diff --git a/tests/allocator.cpp b/tests/allocator.cpp index 094d5e5..74bbf10 100644 --- a/tests/allocator.cpp +++ b/tests/allocator.cpp @@ -66,6 +66,50 @@ namespace VirtualProtect(rptr, aligned_size + PAGE_SIZE, PAGE_NOACCESS, &old_flags); } } +#elif defined(__APPLE__) || defined(__linux__) +# include <sys/mman.h> + +namespace +{ + const size_t PAGE_SIZE = 4096; + + size_t align_to_page(size_t value) + { + return (value + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + } + + void* allocate_page_aligned(size_t size) + { + return mmap(0, size + PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + } + + void* allocate(size_t size) + { + size_t aligned_size = align_to_page(size); + + void* ptr = allocate_page_aligned(aligned_size + PAGE_SIZE); + if (!ptr) return 0; + + char* end = static_cast<char*>(ptr) + aligned_size; + + int res = mprotect(end, PAGE_SIZE, PROT_NONE); + assert(res == 0); + (void)!res; + + return end - size; + } + + void deallocate(void* ptr, size_t size) + { + size_t aligned_size = align_to_page(size); + + void* rptr = static_cast<char*>(ptr) + size - aligned_size; + + int res = mprotect(rptr, aligned_size + PAGE_SIZE, PROT_NONE); + assert(res == 0); + (void)!res; + } +} #else # include <stdlib.h> diff --git a/tests/autotest-local.pl b/tests/autotest-local.pl index a419bb0..60f8b20 100644 --- a/tests/autotest-local.pl +++ b/tests/autotest-local.pl @@ -65,8 +65,8 @@ if ($fast) print "### autotest begin " . scalar localtime() . "\n"; -# print SVN revision info -print "### autotest revision $1\n" if (`svn info` =~ /Revision:\s+(\d+)/); +# print Git revision info +print "### autotest revision $1\n" if (`git rev-parse HEAD` =~ /(.+)/); # get CPU info $cpucount = &getcpucount(); diff --git a/tests/autotest-remote-host.pl b/tests/autotest-remote-host.pl index 5abef1e..63dfe68 100644 --- a/tests/autotest-remote-host.pl +++ b/tests/autotest-remote-host.pl @@ -32,6 +32,6 @@ exit unless $client; select $client; -&execprint('svn up') == 0 || die "error updating from repo\n"; +&execprint('git pull') == 0 || die "error updating from repo\n"; &execprint('perl tests/autotest-local.pl') == 0 || die "error launching tests\n"; system($exitcmd); diff --git a/tests/autotest-report.pl b/tests/autotest-report.pl index b5ebd8c..9eebf39 100644 --- a/tests/autotest-report.pl +++ b/tests/autotest-report.pl @@ -128,7 +128,7 @@ while (<>) $defines{$_} = 1 foreach (split /,/, $defineset); &insertindex(\%configurations, $fullconf); } - elsif (/^### autotest revision (\d+)/) + elsif (/^### autotest revision (.+)/) { if (defined $revision && $revision != $1) { @@ -224,6 +224,6 @@ $date = localtime; print <<END; </table><br> -Generated on $date from Subversion r$revision +Generated on $date from Git $revision </body></html> END diff --git a/tests/data/тест.xml b/tests/data/тест.xml new file mode 100644 index 0000000..6187c16 --- /dev/null +++ b/tests/data/тест.xml @@ -0,0 +1 @@ +<node/>
\ No newline at end of file diff --git a/tests/test.cpp b/tests/test.cpp index eb901db..6347984 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -71,6 +71,15 @@ bool test_double_nan(double value) } #ifndef PUGIXML_NO_XPATH +static size_t strlength(const pugi::char_t* s) +{ +#ifdef PUGIXML_WCHAR_MODE + return wcslen(s); +#else + return strlen(s); +#endif +} + bool test_xpath_string(const pugi::xpath_node& node, const pugi::char_t* query, pugi::xpath_variable_set* variables, const pugi::char_t* expected) { pugi::xpath_query q(query, variables); @@ -81,7 +90,11 @@ bool test_xpath_string(const pugi::xpath_node& node, const pugi::char_t* query, size_t size = q.evaluate_string(result, capacity, node); - if (size <= capacity) return test_string_equal(result, expected); + if (size != strlength(expected) + 1) + return false; + + if (size <= capacity) + return test_string_equal(result, expected); std::basic_string<pugi::char_t> buffer(size, ' '); diff --git a/tests/test.hpp b/tests/test.hpp index 509b0cd..4222638 100644 --- a/tests/test.hpp +++ b/tests/test.hpp @@ -95,7 +95,7 @@ struct dummy_fixture {}; \ test_fixture_##name() \ { \ - CHECK(doc.load(PUGIXML_TEXT(xml), flags)); \ + CHECK(doc.load_string(PUGIXML_TEXT(xml), flags)); \ } \ \ private: \ diff --git a/tests/test_document.cpp b/tests/test_document.cpp index 2774a07..ebcdcd1 100644 --- a/tests/test_document.cpp +++ b/tests/test_document.cpp @@ -158,7 +158,7 @@ TEST(document_load_stream_exceptions) TEST(document_load_stream_error_previous) { pugi::xml_document doc; - CHECK(doc.load(STR("<node/>"))); + CHECK(doc.load_string(STR("<node/>"))); CHECK(doc.first_child()); std::ifstream fs1("filedoesnotexist"); @@ -169,7 +169,7 @@ TEST(document_load_stream_error_previous) TEST(document_load_stream_wide_error_previous) { pugi::xml_document doc; - CHECK(doc.load(STR("<node/>"))); + CHECK(doc.load_string(STR("<node/>"))); CHECK(doc.first_child()); std::basic_ifstream<wchar_t> fs1("filedoesnotexist"); @@ -261,7 +261,7 @@ TEST(document_load_string) { pugi::xml_document doc; - CHECK(doc.load(STR("<node/>"))); + CHECK(doc.load_string(STR("<node/>"))); CHECK_NODE(doc, STR("<node />")); } @@ -301,10 +301,6 @@ TEST(document_load_file_error) CHECK(doc.load_file("filedoesnotexist").status == status_file_not_found); -#ifndef _WIN32 - CHECK(doc.load_file("/dev/tty").status == status_io_error); -#endif - test_runner::_memory_fail_threshold = 1; CHECK(doc.load_file("tests/data/small.xml").status == status_out_of_memory); } @@ -312,7 +308,7 @@ TEST(document_load_file_error) TEST(document_load_file_error_previous) { pugi::xml_document doc; - CHECK(doc.load(STR("<node/>"))); + CHECK(doc.load_string(STR("<node/>"))); CHECK(doc.first_child()); CHECK(doc.load_file("filedoesnotexist").status == status_file_not_found); @@ -327,6 +323,16 @@ TEST(document_load_file_wide_ascii) CHECK_NODE(doc, STR("<node />")); } +#if !defined(__DMC__) && !defined(__MWERKS__) && !(defined(__MINGW32__) && defined(__STRICT_ANSI__) && !defined(__MINGW64_VERSION_MAJOR)) +TEST(document_load_file_wide_unicode) +{ + pugi::xml_document doc; + + CHECK(doc.load_file(L"tests/data/\x0442\x0435\x0441\x0442.xml")); + CHECK_NODE(doc, STR("<node />")); +} +#endif + TEST(document_load_file_wide_out_of_memory) { test_runner::_memory_fail_threshold = 1; @@ -594,7 +600,7 @@ TEST(document_parse_result_description) TEST(document_load_fail) { xml_document doc; - CHECK(!doc.load(STR("<foo><bar/>"))); + CHECK(!doc.load_string(STR("<foo><bar/>"))); CHECK(doc.child(STR("foo")).child(STR("bar"))); } @@ -1083,7 +1089,7 @@ TEST(document_load_exceptions) try { pugi::xml_document doc; - if (!doc.load(STR("<node attribute='value"))) throw std::bad_alloc(); + if (!doc.load_string(STR("<node attribute='value"))) throw std::bad_alloc(); CHECK_FORCE_FAIL("Expected parsing failure"); } @@ -1118,7 +1124,7 @@ TEST_XML(document_reset, "<node><child/></node>") CHECK(!doc.first_child()); CHECK_NODE(doc, STR("")); - CHECK(doc.load(STR("<node/>"))); + CHECK(doc.load_string(STR("<node/>"))); CHECK(doc.first_child()); CHECK_NODE(doc, STR("<node />")); @@ -1272,7 +1278,7 @@ TEST(document_alignment) { xml_document* doc = new (buf + offset) xml_document; - CHECK(doc->load(STR("<node />"))); + CHECK(doc->load_string(STR("<node />"))); CHECK_NODE(*doc, STR("<node />")); doc->~xml_document(); @@ -1312,3 +1318,10 @@ TEST(document_convert_out_of_memory) delete[] files[j].data; } } + +TEST(document_deprecated_load) +{ + xml_document doc; + CHECK(doc.load(STR("<node/>"))); + CHECK_NODE(doc, STR("<node />")); +} diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp index 45cf3ea..5167358 100644 --- a/tests/test_dom_modify.cpp +++ b/tests/test_dom_modify.cpp @@ -3,6 +3,8 @@ #include <limits> #include <string> +#include <math.h> + TEST_XML(dom_attr_assign, "<node/>") { xml_node node = doc.child(STR("node")); @@ -21,10 +23,13 @@ TEST_XML(dom_attr_assign, "<node/>") node.append_attribute(STR("attr6")) = 0.5; xml_attribute() = 0.5; - node.append_attribute(STR("attr7")) = true; + node.append_attribute(STR("attr7")) = 0.25f; + xml_attribute() = 0.25f; + + node.append_attribute(STR("attr8")) = true; xml_attribute() = true; - CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"true\" />")); + CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\" />")); } TEST_XML(dom_attr_set_name, "<node attr='value' />") @@ -55,10 +60,13 @@ TEST_XML(dom_attr_set_value, "<node/>") CHECK(node.append_attribute(STR("attr6")).set_value(0.5)); CHECK(!xml_attribute().set_value(0.5)); - CHECK(node.append_attribute(STR("attr7")).set_value(true)); + CHECK(node.append_attribute(STR("attr7")).set_value(0.25f)); + CHECK(!xml_attribute().set_value(0.25f)); + + CHECK(node.append_attribute(STR("attr8")).set_value(true)); CHECK(!xml_attribute().set_value(true)); - CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"true\" />")); + CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\" />")); } #ifdef PUGIXML_HAS_LONG_LONG @@ -93,6 +101,17 @@ TEST_XML(dom_attr_set_value_llong, "<node/>") } #endif +TEST_XML(dom_attr_assign_large_number, "<node attr1='' attr2='' />") +{ + xml_node node = doc.child(STR("node")); + + node.attribute(STR("attr1")) = std::numeric_limits<float>::max(); + node.attribute(STR("attr2")) = std::numeric_limits<double>::max(); + + CHECK(test_node(node, STR("<node attr1=\"3.40282347e+038\" attr2=\"1.7976931348623157e+308\" />"), STR(""), pugi::format_raw) || + test_node(node, STR("<node attr1=\"3.40282347e+38\" attr2=\"1.7976931348623157e+308\" />"), STR(""), pugi::format_raw)); +} + TEST_XML(dom_node_set_name, "<node>text</node>") { CHECK(doc.child(STR("node")).set_name(STR("n"))); @@ -746,17 +765,6 @@ TEST_XML_FLAGS(dom_node_copy_types, "<?xml version='1.0'?><!DOCTYPE id><root><?p CHECK_NODE(doc, STR("<?xml version=\"1.0\"?><!DOCTYPE id><?xml version=\"1.0\"?><!DOCTYPE id><root><?pi value?><!--comment--><node id=\"1\">pcdata<![CDATA[cdata]]></node></root><root><?pi value?><!--comment--><node id=\"1\">pcdata<![CDATA[cdata]]></node></root>")); } -TEST_XML(dom_attr_assign_large_number, "<node attr1='' attr2='' />") -{ - xml_node node = doc.child(STR("node")); - - node.attribute(STR("attr1")) = std::numeric_limits<float>::max(); - node.attribute(STR("attr2")) = std::numeric_limits<double>::max(); - - CHECK(test_node(node, STR("<node attr1=\"3.40282e+038\" attr2=\"1.79769e+308\" />"), STR(""), pugi::format_raw) || - test_node(node, STR("<node attr1=\"3.40282e+38\" attr2=\"1.79769e+308\" />"), STR(""), pugi::format_raw)); -} - TEST(dom_node_declaration_name) { xml_document doc; @@ -1289,7 +1297,7 @@ TEST(dom_node_copy_stackless) data += STR("</a>"); xml_document doc; - CHECK(doc.load(data.c_str())); + CHECK(doc.load_string(data.c_str())); xml_document copy; CHECK(copy.append_copy(doc.first_child())); @@ -1324,7 +1332,7 @@ TEST(dom_node_copy_copyless) TEST(dom_node_copy_copyless_mix) { xml_document doc; - CHECK(doc.load(STR("<node>pcdata<?name value?><child attr1=\"\" attr2=\"value2\" /></node>"), parse_full)); + CHECK(doc.load_string(STR("<node>pcdata<?name value?><child attr1=\"\" attr2=\"value2\" /></node>"), parse_full)); xml_node child = doc.child(STR("node")).child(STR("child")); @@ -1426,3 +1434,76 @@ TEST_XML(dom_node_set_deallocate, "<node attr='value'>text</node>") CHECK_NODE(doc, STR("<:anonymous :anonymous=\"\"></:anonymous>")); } + +TEST(dom_node_copy_declaration_empty_name) +{ + xml_document doc1; + xml_node decl1 = doc1.append_child(node_declaration); + decl1.set_name(STR("")); + + xml_document doc2; + xml_node decl2 = doc2.append_copy(decl1); + + CHECK_STRING(decl2.name(), STR("")); +} + +TEST(dom_fp_roundtrip_min_max) +{ + xml_document doc; + xml_node node = doc.append_child(STR("node")); + xml_attribute attr = node.append_attribute(STR("attr")); + + node.text().set(std::numeric_limits<float>::min()); + CHECK(node.text().as_float() == std::numeric_limits<float>::min()); + + attr.set_value(std::numeric_limits<float>::max()); + CHECK(attr.as_float() == std::numeric_limits<float>::max()); + + attr.set_value(std::numeric_limits<double>::min()); + CHECK(attr.as_double() == std::numeric_limits<double>::min()); + + node.text().set(std::numeric_limits<double>::max()); + CHECK(node.text().as_double() == std::numeric_limits<double>::max()); +} + +const double fp_roundtrip_base[] = +{ + 0.31830988618379067154, + 0.43429448190325182765, + 0.57721566490153286061, + 0.69314718055994530942, + 0.70710678118654752440, + 0.78539816339744830962, +}; + +TEST(dom_fp_roundtrip_float) +{ + xml_document doc; + + for (int e = -125; e <= 128; ++e) + { + for (size_t i = 0; i < sizeof(fp_roundtrip_base) / sizeof(fp_roundtrip_base[0]); ++i) + { + float value = ldexpf(static_cast<float>(fp_roundtrip_base[i]), e); + + doc.text().set(value); + CHECK(doc.text().as_float() == value); + } + } +} + +TEST(dom_fp_roundtrip_double) +{ + xml_document doc; + + for (int e = -1021; e <= 1024; ++e) + { + for (size_t i = 0; i < sizeof(fp_roundtrip_base) / sizeof(fp_roundtrip_base[0]); ++i) + { + double value = ldexp(fp_roundtrip_base[i], e); + + doc.text().set(value); + CHECK(doc.text().as_double() == value); + } + } +} diff --git a/tests/test_dom_text.cpp b/tests/test_dom_text.cpp index fb65b03..007334a 100644 --- a/tests/test_dom_text.cpp +++ b/tests/test_dom_text.cpp @@ -263,10 +263,13 @@ TEST_XML(dom_text_assign, "<node/>") node.append_child(STR("text6")).text() = 0.5;
xml_text() = 0.5;
- node.append_child(STR("text7")).text() = true;
+ node.append_child(STR("text7")).text() = 0.25f;
+ xml_text() = 0.25f;
+
+ node.append_child(STR("text8")).text() = true;
xml_text() = true;
- CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>true</text7></node>"));
+ CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>0.25</text7><text8>true</text8></node>"));
}
TEST_XML(dom_text_set_value, "<node/>")
@@ -287,10 +290,13 @@ TEST_XML(dom_text_set_value, "<node/>") CHECK(node.append_child(STR("text6")).text().set(0.5));
CHECK(!xml_text().set(0.5));
- CHECK(node.append_child(STR("text7")).text().set(true));
+ CHECK(node.append_child(STR("text7")).text().set(0.25f));
+ CHECK(!xml_text().set(0.25f));
+
+ CHECK(node.append_child(STR("text8")).text().set(true));
CHECK(!xml_text().set(true));
- CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>true</text7></node>"));
+ CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>0.25</text7><text8>true</text8></node>"));
}
#ifdef PUGIXML_HAS_LONG_LONG
diff --git a/tests/test_dom_traverse.cpp b/tests/test_dom_traverse.cpp index 83afec8..721a079 100644 --- a/tests/test_dom_traverse.cpp +++ b/tests/test_dom_traverse.cpp @@ -924,6 +924,43 @@ TEST_XML_FLAGS(dom_offset_debug, "<?xml?><!DOCTYPE><?pi?><!--comment--><node>pcd CHECK((cit++)->offset_debug() == 58); } +TEST(dom_offset_debug_encoding) +{ + char buf[] = { 0, '<', 0, 'n', 0, '/', 0, '>' }; + + xml_document doc; + CHECK(doc.load_buffer(buf, sizeof(buf))); + + CHECK(doc.offset_debug() == 0); + CHECK(doc.first_child().offset_debug() == 1); +} + +TEST_XML(dom_offset_debug_append, "<node/>") +{ + xml_node c1 = doc.first_child(); + xml_node c2 = doc.append_child(STR("node")); + xml_node c3 = doc.append_child(node_pcdata); + + CHECK(doc.offset_debug() == 0); + CHECK(c1.offset_debug() == 1); + CHECK(c2.offset_debug() == -1); + CHECK(c3.offset_debug() == -1); + + c1.set_name(STR("nodenode")); + CHECK(c1.offset_debug() == -1); +} + +TEST_XML(dom_offset_debug_append_buffer, "<node/>") +{ + CHECK(doc.offset_debug() == 0); + CHECK(doc.first_child().offset_debug() == 1); + + CHECK(doc.append_buffer("<node/>", 7)); + CHECK(doc.offset_debug() == -1); + CHECK(doc.first_child().offset_debug() == -1); + CHECK(doc.last_child().offset_debug() == -1); +} + TEST_XML(dom_internal_object, "<node attr='value'>value</node>") { xml_node node = doc.child(STR("node")); diff --git a/tests/test_header_only.cpp b/tests/test_header_only.cpp new file mode 100644 index 0000000..f1990dd --- /dev/null +++ b/tests/test_header_only.cpp @@ -0,0 +1,16 @@ +#define PUGIXML_HEADER_ONLY +#define pugi pugih + +#include "common.hpp" + +// Check header guards +#include "../src/pugixml.hpp" +#include "../src/pugixml.hpp" + +TEST(header_only) +{ + xml_document doc; + CHECK(doc.load_string(STR("<node/>"))); + CHECK_STRING(doc.first_child().name(), STR("node")); + CHECK(doc.first_child() == doc.select_node(STR("//*")).node()); +} diff --git a/tests/test_memory.cpp b/tests/test_memory.cpp index 32d395b..bd80ca1 100644 --- a/tests/test_memory.cpp +++ b/tests/test_memory.cpp @@ -39,7 +39,7 @@ TEST(memory_custom_memory_management) CHECK(allocate_count == 0 && deallocate_count == 0); - CHECK(doc.load(STR("<node />"))); + CHECK(doc.load_string(STR("<node />"))); CHECK(allocate_count == 2 && deallocate_count == 0); diff --git a/tests/test_parse.cpp b/tests/test_parse.cpp index 56ea049..500e44c 100644 --- a/tests/test_parse.cpp +++ b/tests/test_parse.cpp @@ -12,10 +12,10 @@ TEST(parse_pi_skip) { unsigned int flags = flag_sets[i]; - CHECK(doc.load(STR("<?pi?><?pi value?>"), flags)); + CHECK(doc.load_string(STR("<?pi?><?pi value?>"), flags)); CHECK(!doc.first_child()); - CHECK(doc.load(STR("<?pi <tag/> value?>"), flags)); + CHECK(doc.load_string(STR("<?pi <tag/> value?>"), flags)); CHECK(!doc.first_child()); } } @@ -23,7 +23,7 @@ TEST(parse_pi_skip) TEST(parse_pi_parse) { xml_document doc; - CHECK(doc.load(STR("<?pi1?><?pi2 value?>"), parse_fragment | parse_pi)); + CHECK(doc.load_string(STR("<?pi1?><?pi2 value?>"), parse_fragment | parse_pi)); xml_node pi1 = doc.first_child(); xml_node pi2 = doc.last_child(); @@ -40,7 +40,7 @@ TEST(parse_pi_parse) TEST(parse_pi_parse_spaces) { xml_document doc; - CHECK(doc.load(STR("<?target \r\n\t value ?>"), parse_fragment | parse_pi)); + CHECK(doc.load_string(STR("<?target \r\n\t value ?>"), parse_fragment | parse_pi)); xml_node pi = doc.first_child(); @@ -59,46 +59,46 @@ TEST(parse_pi_error) { unsigned int flags = flag_sets[i]; - CHECK(doc.load(STR("<?"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<??"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?>"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?#?>"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name>"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name ?"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name?"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name? "), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name? "), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name "), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name "), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name "), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name value"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name value "), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name value "), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name value ?"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name value ? "), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name value ? >"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name value ? > "), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name&"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?name&?"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<??"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?>"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?#?>"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name>"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name ?"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name?"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name? "), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name? "), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name "), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name "), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name "), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name value"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name value "), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name value "), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name value ?"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name value ? "), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name value ? >"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name value ? > "), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name&"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name&?"), flags).status == status_bad_pi); } - CHECK(doc.load(STR("<?xx#?>"), parse_fragment | parse_pi).status == status_bad_pi); - CHECK(doc.load(STR("<?name&?>"), parse_fragment | parse_pi).status == status_bad_pi); - CHECK(doc.load(STR("<?name& x?>"), parse_fragment | parse_pi).status == status_bad_pi); + CHECK(doc.load_string(STR("<?xx#?>"), parse_fragment | parse_pi).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name&?>"), parse_fragment | parse_pi).status == status_bad_pi); + CHECK(doc.load_string(STR("<?name& x?>"), parse_fragment | parse_pi).status == status_bad_pi); } TEST(parse_comments_skip) { xml_document doc; - CHECK(doc.load(STR("<!----><!--value-->"), parse_fragment)); + CHECK(doc.load_string(STR("<!----><!--value-->"), parse_fragment)); CHECK(!doc.first_child()); } TEST(parse_comments_parse) { xml_document doc; - CHECK(doc.load(STR("<!----><!--value-->"), parse_fragment | parse_comments)); + CHECK(doc.load_string(STR("<!----><!--value-->"), parse_fragment | parse_comments)); xml_node c1 = doc.first_child(); xml_node c2 = doc.last_child(); @@ -115,7 +115,7 @@ TEST(parse_comments_parse) TEST(parse_comments_parse_no_eol) { xml_document doc; - CHECK(doc.load(STR("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->"), parse_fragment | parse_comments)); + CHECK(doc.load_string(STR("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->"), parse_fragment | parse_comments)); xml_node c = doc.first_child(); CHECK(c.type() == node_comment); @@ -125,7 +125,7 @@ TEST(parse_comments_parse_no_eol) TEST(parse_comments_parse_eol) { xml_document doc; - CHECK(doc.load(STR("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->"), parse_fragment | parse_comments | parse_eol)); + CHECK(doc.load_string(STR("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->"), parse_fragment | parse_comments | parse_eol)); xml_node c = doc.first_child(); CHECK(c.type() == node_comment); @@ -142,33 +142,33 @@ TEST(parse_comments_error) { unsigned int flags = flag_sets[i]; - CHECK(doc.load(STR("<!-"), flags).status == status_bad_comment); - CHECK(doc.load(STR("<!--"), flags).status == status_bad_comment); - CHECK(doc.load(STR("<!--v"), flags).status == status_bad_comment); - CHECK(doc.load(STR("<!-->"), flags).status == status_bad_comment); - CHECK(doc.load(STR("<!--->"), flags).status == status_bad_comment); - CHECK(doc.load(STR("<!-- <!-- --><!- -->"), flags).status == status_bad_comment); + CHECK(doc.load_string(STR("<!-"), flags).status == status_bad_comment); + CHECK(doc.load_string(STR("<!--"), flags).status == status_bad_comment); + CHECK(doc.load_string(STR("<!--v"), flags).status == status_bad_comment); + CHECK(doc.load_string(STR("<!-->"), flags).status == status_bad_comment); + CHECK(doc.load_string(STR("<!--->"), flags).status == status_bad_comment); + CHECK(doc.load_string(STR("<!-- <!-- --><!- -->"), flags).status == status_bad_comment); } } TEST(parse_cdata_skip) { xml_document doc; - CHECK(doc.load(STR("<![CDATA[]]><![CDATA[value]]>"), parse_fragment)); + CHECK(doc.load_string(STR("<![CDATA[]]><![CDATA[value]]>"), parse_fragment)); CHECK(!doc.first_child()); } TEST(parse_cdata_skip_contents) { xml_document doc; - CHECK(doc.load(STR("<node><![CDATA[]]>hello<![CDATA[value]]>, world!</node>"), parse_fragment)); + CHECK(doc.load_string(STR("<node><![CDATA[]]>hello<![CDATA[value]]>, world!</node>"), parse_fragment)); CHECK_NODE(doc, STR("<node>hello, world!</node>")); } TEST(parse_cdata_parse) { xml_document doc; - CHECK(doc.load(STR("<![CDATA[]]><![CDATA[value]]>"), parse_fragment | parse_cdata)); + CHECK(doc.load_string(STR("<![CDATA[]]><![CDATA[value]]>"), parse_fragment | parse_cdata)); xml_node c1 = doc.first_child(); xml_node c2 = doc.last_child(); @@ -185,7 +185,7 @@ TEST(parse_cdata_parse) TEST(parse_cdata_parse_no_eol) { xml_document doc; - CHECK(doc.load(STR("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>"), parse_fragment | parse_cdata)); + CHECK(doc.load_string(STR("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>"), parse_fragment | parse_cdata)); xml_node c = doc.first_child(); CHECK(c.type() == node_cdata); @@ -195,7 +195,7 @@ TEST(parse_cdata_parse_no_eol) TEST(parse_cdata_parse_eol) { xml_document doc; - CHECK(doc.load(STR("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>"), parse_fragment | parse_cdata | parse_eol)); + CHECK(doc.load_string(STR("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>"), parse_fragment | parse_cdata | parse_eol)); xml_node c = doc.first_child(); CHECK(c.type() == node_cdata); @@ -212,29 +212,29 @@ TEST(parse_cdata_error) { unsigned int flags = flag_sets[i]; - CHECK(doc.load(STR("<!["), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![C"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CD"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDA"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDAT"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDATA"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDATA["), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDATA[]"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDATA[data"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDATA[data]"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDATA[data]]"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDATA[>"), flags).status == status_bad_cdata); - CHECK(doc.load(STR("<![CDATA[ <![CDATA[]]><![CDATA ]]>"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<!["), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![C"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CD"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDA"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDAT"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDATA"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDATA["), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDATA[]"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDATA[data"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDATA[data]"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDATA[data]]"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDATA[>"), flags).status == status_bad_cdata); + CHECK(doc.load_string(STR("<![CDATA[ <![CDATA[]]><![CDATA ]]>"), flags).status == status_bad_cdata); } } TEST(parse_ws_pcdata_skip) { xml_document doc; - CHECK(doc.load(STR(" "), parse_fragment)); + CHECK(doc.load_string(STR(" "), parse_fragment)); CHECK(!doc.first_child()); - CHECK(doc.load(STR("<root> <node> </node> </root>"), parse_minimal)); + CHECK(doc.load_string(STR("<root> <node> </node> </root>"), parse_minimal)); xml_node root = doc.child(STR("root")); @@ -245,7 +245,7 @@ TEST(parse_ws_pcdata_skip) TEST(parse_ws_pcdata_parse) { xml_document doc; - CHECK(doc.load(STR("<root> <node> </node> </root>"), parse_minimal | parse_ws_pcdata)); + CHECK(doc.load_string(STR("<root> <node> </node> </root>"), parse_minimal | parse_ws_pcdata)); xml_node root = doc.child(STR("root")); @@ -334,7 +334,7 @@ TEST(parse_ws_pcdata_permutations) unsigned int flags[] = {parse_default, parse_default | parse_ws_pcdata, parse_default | parse_ws_pcdata_single}; xml_document doc; - CHECK((td.nodes > 0) == doc.load(td.source, flags[flag])); + CHECK((td.nodes > 0) == doc.load_string(td.source, flags[flag])); CHECK_NODE(doc, td.result); int nodes = get_tree_node_count(doc); @@ -385,7 +385,7 @@ TEST(parse_ws_pcdata_fragment_permutations) unsigned int flags[] = {parse_default, parse_default | parse_ws_pcdata, parse_default | parse_ws_pcdata_single}; xml_document doc; - CHECK((td.nodes > 0) == doc.load(td.source, flags[flag] | parse_fragment)); + CHECK((td.nodes > 0) == doc.load_string(td.source, flags[flag] | parse_fragment)); CHECK_NODE(doc, td.result); int nodes = get_tree_node_count(doc); @@ -398,7 +398,7 @@ TEST(parse_ws_pcdata_fragment_permutations) TEST(parse_pcdata_no_eol) { xml_document doc; - CHECK(doc.load(STR("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>"), parse_minimal)); + CHECK(doc.load_string(STR("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>"), parse_minimal)); CHECK_STRING(doc.child_value(STR("root")), STR("\r\rval1\rval2\r\nval3\nval4\r\r")); } @@ -406,7 +406,7 @@ TEST(parse_pcdata_no_eol) TEST(parse_pcdata_eol) { xml_document doc; - CHECK(doc.load(STR("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>"), parse_minimal | parse_eol)); + CHECK(doc.load_string(STR("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>"), parse_minimal | parse_eol)); CHECK_STRING(doc.child_value(STR("root")), STR("\n\nval1\nval2\nval3\nval4\n\n")); } @@ -414,7 +414,7 @@ TEST(parse_pcdata_eol) TEST(parse_pcdata_skip_ext) { xml_document doc; - CHECK(doc.load(STR("pre<root/>post"), parse_minimal)); + CHECK(doc.load_string(STR("pre<root/>post"), parse_minimal)); CHECK(doc.first_child() == doc.last_child()); CHECK(doc.first_child().type() == node_element); } @@ -422,7 +422,7 @@ TEST(parse_pcdata_skip_ext) TEST(parse_pcdata_error) { xml_document doc; - CHECK(doc.load(STR("<root>pcdata"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("<root>pcdata"), parse_minimal).status == status_end_element_mismatch); } TEST(parse_pcdata_trim) @@ -460,7 +460,7 @@ TEST(parse_pcdata_trim) const test_data_t& td = test_data[i]; xml_document doc; - CHECK(doc.load(td.source, td.flags | parse_trim_pcdata)); + CHECK(doc.load_string(td.source, td.flags | parse_trim_pcdata)); const pugi::char_t* value = doc.child(STR("node")) ? doc.child_value(STR("node")) : doc.text().get(); CHECK_STRING(value, td.result); @@ -474,7 +474,7 @@ TEST(parse_pcdata_trim_empty) for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) { xml_document doc; - CHECK(doc.load(STR("<node> </node>"), flags[i] | parse_trim_pcdata)); + CHECK(doc.load_string(STR("<node> </node>"), flags[i] | parse_trim_pcdata)); xml_node node = doc.child(STR("node")); CHECK(node); @@ -485,14 +485,14 @@ TEST(parse_pcdata_trim_empty) TEST(parse_escapes_skip) { xml_document doc; - CHECK(doc.load(STR("<node id='<>&'"'><>&'"</node>"), parse_minimal)); + CHECK(doc.load_string(STR("<node id='<>&'"'><>&'"</node>"), parse_minimal)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("<>&'"")); } TEST(parse_escapes_parse) { xml_document doc; - CHECK(doc.load(STR("<node id='<>&'"'><>&'"</node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node id='<>&'"'><>&'"</node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("<>&'\"")); CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("<>&'\"")); } @@ -500,28 +500,28 @@ TEST(parse_escapes_parse) TEST(parse_escapes_code) { xml_document doc; - CHECK(doc.load(STR("<node>  </node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>  </node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("\01 ")); } TEST(parse_escapes_code_exhaustive_dec) { xml_document doc; - CHECK(doc.load(STR("<node>&#/;	&#:;&#a;&#A;
</node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>&#/;	&#:;&#a;&#A;
</node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("&#/;\x1\x2\x3\x4\x5\x6\x7\x8\x9&#:;&#a;&#A;
")); } TEST(parse_escapes_code_exhaustive_hex) { xml_document doc; - CHECK(doc.load(STR("<node>&#x/;	&#x:;&#x@;

&#xG;&#x`;

&#xg;</node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>&#x/;	&#x:;&#x@;

&#xG;&#x`;

&#xg;</node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("&#x/;\x1\x2\x3\x4\x5\x6\x7\x8\x9&#x:;&#x@;\xa\xb\xc\xd\xe\xf&#xG;&#x`;\xa\xb\xc\xd\xe\xf&#xg;")); } TEST(parse_escapes_code_restore) { xml_document doc; - CHECK(doc.load(STR("<node>  - - </node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>  - - </node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("  - - ")); } @@ -529,26 +529,26 @@ TEST(parse_escapes_char_restore) { xml_document doc; - CHECK(doc.load(STR("<node>&q &qu &quo " </node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>&q &qu &quo " </node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("&q &qu &quo " ")); - CHECK(doc.load(STR("<node>&a &ap &apo &apos </node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>&a &ap &apo &apos </node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("&a &ap &apo &apos ")); - CHECK(doc.load(STR("<node>&a &am & </node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>&a &am & </node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("&a &am & ")); - CHECK(doc.load(STR("<node>&l < </node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>&l < </node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("&l < ")); - CHECK(doc.load(STR("<node>&g > </node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>&g > </node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("&g > ")); } TEST(parse_escapes_unicode) { xml_document doc; - CHECK(doc.load(STR("<node>γγ𤭢</node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>γγ𤭢</node>"), parse_minimal | parse_escapes)); #ifdef PUGIXML_WCHAR_MODE const pugi::char_t* v = doc.child_value(STR("node")); @@ -564,23 +564,23 @@ TEST(parse_escapes_unicode) TEST(parse_escapes_error) { xml_document doc; - CHECK(doc.load(STR("<node>g;&#ab;"</node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>g;&#ab;"</node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("g;&#ab;"")); - CHECK(!doc.load(STR("<node id='"))); - CHECK(!doc.load(STR("<node id='&g"))); - CHECK(!doc.load(STR("<node id='>"))); - CHECK(!doc.load(STR("<node id='&l"))); - CHECK(!doc.load(STR("<node id='<"))); - CHECK(!doc.load(STR("<node id='&a"))); - CHECK(!doc.load(STR("<node id='&"))); - CHECK(!doc.load(STR("<node id='&apos"))); + CHECK(!doc.load_string(STR("<node id='"))); + CHECK(!doc.load_string(STR("<node id='&g"))); + CHECK(!doc.load_string(STR("<node id='>"))); + CHECK(!doc.load_string(STR("<node id='&l"))); + CHECK(!doc.load_string(STR("<node id='<"))); + CHECK(!doc.load_string(STR("<node id='&a"))); + CHECK(!doc.load_string(STR("<node id='&"))); + CHECK(!doc.load_string(STR("<node id='&apos"))); } TEST(parse_escapes_code_invalid) { xml_document doc; - CHECK(doc.load(STR("<node>&#;&#x;&;&#x-;&#-;</node>"), parse_minimal | parse_escapes)); + CHECK(doc.load_string(STR("<node>&#;&#x;&;&#x-;&#-;</node>"), parse_minimal | parse_escapes)); CHECK_STRING(doc.child_value(STR("node")), STR("&#;&#x;&;&#x-;&#-;")); } @@ -598,7 +598,7 @@ TEST(parse_escapes_attribute) flags |= (eol ? parse_eol : 0); flags |= (wconv ? parse_wconv_attribute : 0); - CHECK(doc.load(STR("<node id='"'/>"), flags)); + CHECK(doc.load_string(STR("<node id='"'/>"), flags)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("\"")); } } @@ -606,7 +606,7 @@ TEST(parse_escapes_attribute) TEST(parse_attribute_spaces) { xml_document doc; - CHECK(doc.load(STR("<node id1='v1' id2 ='v2' id3= 'v3' id4 = 'v4' id5 \n\r\t = \r\t\n 'v5' />"), parse_minimal)); + CHECK(doc.load_string(STR("<node id1='v1' id2 ='v2' id3= 'v3' id4 = 'v4' id5 \n\r\t = \r\t\n 'v5' />"), parse_minimal)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id1")).value(), STR("v1")); CHECK_STRING(doc.child(STR("node")).attribute(STR("id2")).value(), STR("v2")); CHECK_STRING(doc.child(STR("node")).attribute(STR("id3")).value(), STR("v3")); @@ -617,7 +617,7 @@ TEST(parse_attribute_spaces) TEST(parse_attribute_quot) { xml_document doc; - CHECK(doc.load(STR("<node id1='v1' id2=\"v2\"/>"), parse_minimal)); + CHECK(doc.load_string(STR("<node id1='v1' id2=\"v2\"/>"), parse_minimal)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id1")).value(), STR("v1")); CHECK_STRING(doc.child(STR("node")).attribute(STR("id2")).value(), STR("v2")); } @@ -625,28 +625,28 @@ TEST(parse_attribute_quot) TEST(parse_attribute_no_eol_no_wconv) { xml_document doc; - CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal)); + CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" \t\r\rval1 \rval2\r\nval3\nval4\r\r")); } TEST(parse_attribute_eol_no_wconv) { xml_document doc; - CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_eol)); + CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_eol)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" \t\n\nval1 \nval2\nval3\nval4\n\n")); } TEST(parse_attribute_no_eol_wconv) { xml_document doc; - CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_wconv_attribute)); + CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_wconv_attribute)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" val1 val2 val3 val4 ")); } TEST(parse_attribute_eol_wconv) { xml_document doc; - CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_eol | parse_wconv_attribute)); + CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_eol | parse_wconv_attribute)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" val1 val2 val3 val4 ")); } @@ -658,7 +658,7 @@ TEST(parse_attribute_wnorm) for (int wconv = 0; wconv < 2; ++wconv) { unsigned int flags = parse_minimal | parse_wnorm_attribute | (eol ? parse_eol : 0) | (wconv ? parse_wconv_attribute : 0); - CHECK(doc.load(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), flags)); + CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), flags)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("val1 val2 val3 val4")); } } @@ -679,7 +679,7 @@ TEST(parse_attribute_variations) flags |= (wconv ? parse_wconv_attribute : 0); flags |= (escapes ? parse_escapes : 0); - CHECK(doc.load(STR("<node id='1'/>"), flags)); + CHECK(doc.load_string(STR("<node id='1'/>"), flags)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("1")); } } @@ -688,24 +688,24 @@ TEST(parse_attribute_variations) TEST(parse_attribute_error) { xml_document doc; - CHECK(doc.load(STR("<node id"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id "), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id "), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id "), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id/"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id?/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id=/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id='/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id=\"/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id=\"'/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id='\"/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id='\"/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node #/>"), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("<node#/>"), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("<node id1='1'id2='2'/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node id&='1'/>"), parse_minimal).status == status_bad_attribute); - CHECK(doc.load(STR("<node &='1'/>"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node id"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id "), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id "), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id "), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id/"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id?/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id=/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id='/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id=\"/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id=\"'/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id='\"/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id='\"/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node #/>"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node#/>"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node id1='1'id2='2'/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id&='1'/>"), parse_minimal).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node &='1'/>"), parse_minimal).status == status_bad_start_element); } TEST(parse_attribute_termination_error) @@ -722,7 +722,7 @@ TEST(parse_attribute_termination_error) flags |= (eol ? parse_eol : 0); flags |= (wconv ? parse_wconv_attribute : 0); - CHECK(doc.load(STR("<node id='value"), flags).status == status_bad_attribute); + CHECK(doc.load_string(STR("<node id='value"), flags).status == status_bad_attribute); } } @@ -740,7 +740,7 @@ TEST(parse_attribute_quot_inside) flags |= (eol ? parse_eol : 0); flags |= (wconv ? parse_wconv_attribute : 0); - CHECK(doc.load(STR("<node id1='\"' id2=\"'\"/>"), flags)); + CHECK(doc.load_string(STR("<node id1='\"' id2=\"'\"/>"), flags)); CHECK_STRING(doc.child(STR("node")).attribute(STR("id1")).value(), STR("\"")); CHECK_STRING(doc.child(STR("node")).attribute(STR("id2")).value(), STR("'")); } @@ -749,60 +749,60 @@ TEST(parse_attribute_quot_inside) TEST(parse_tag_single) { xml_document doc; - CHECK(doc.load(STR("<node/><node /><node\n/>"), parse_minimal)); + CHECK(doc.load_string(STR("<node/><node /><node\n/>"), parse_minimal)); CHECK_NODE(doc, STR("<node /><node /><node />")); } TEST(parse_tag_hierarchy) { xml_document doc; - CHECK(doc.load(STR("<node><n1><n2/></n1><n3><n4><n5></n5></n4></n3 \r\n></node>"), parse_minimal)); + CHECK(doc.load_string(STR("<node><n1><n2/></n1><n3><n4><n5></n5></n4></n3 \r\n></node>"), parse_minimal)); CHECK_NODE(doc, STR("<node><n1><n2 /></n1><n3><n4><n5 /></n4></n3></node>")); } TEST(parse_tag_error) { xml_document doc; - CHECK(doc.load(STR("<"), parse_minimal).status == status_unrecognized_tag); - CHECK(doc.load(STR("<!"), parse_minimal).status == status_unrecognized_tag); - CHECK(doc.load(STR("<!D"), parse_minimal).status == status_unrecognized_tag); - CHECK(doc.load(STR("<#"), parse_minimal).status == status_unrecognized_tag); - CHECK(doc.load(STR("<node#"), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("<node"), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("<node/"), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("<node /"), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("<node / "), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("<node / >"), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("<node/ >"), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("</ node>"), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("</node"), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("</node "), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("<node></ node>"), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("<node></node"), parse_minimal).status == status_bad_end_element); - CHECK(doc.load(STR("<node></node "), parse_minimal).status == status_bad_end_element); - CHECK(doc.load(STR("<node></nodes>"), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("<node>"), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("<node/><"), parse_minimal).status == status_unrecognized_tag); - CHECK(doc.load(STR("<node attr='value'>"), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("</></node>"), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("</node>"), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("</>"), parse_minimal).status == status_end_element_mismatch); - CHECK(doc.load(STR("<node></node v>"), parse_minimal).status == status_bad_end_element); - CHECK(doc.load(STR("<node&/>"), parse_minimal).status == status_bad_start_element); - CHECK(doc.load(STR("<node& v='1'/>"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<"), parse_minimal).status == status_unrecognized_tag); + CHECK(doc.load_string(STR("<!"), parse_minimal).status == status_unrecognized_tag); + CHECK(doc.load_string(STR("<!D"), parse_minimal).status == status_unrecognized_tag); + CHECK(doc.load_string(STR("<#"), parse_minimal).status == status_unrecognized_tag); + CHECK(doc.load_string(STR("<node#"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node/"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node /"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node / "), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node / >"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node/ >"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("</ node>"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("</node"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("</node "), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("<node></ node>"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("<node></node"), parse_minimal).status == status_bad_end_element); + CHECK(doc.load_string(STR("<node></node "), parse_minimal).status == status_bad_end_element); + CHECK(doc.load_string(STR("<node></nodes>"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("<node>"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("<node/><"), parse_minimal).status == status_unrecognized_tag); + CHECK(doc.load_string(STR("<node attr='value'>"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("</></node>"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("</node>"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("</>"), parse_minimal).status == status_end_element_mismatch); + CHECK(doc.load_string(STR("<node></node v>"), parse_minimal).status == status_bad_end_element); + CHECK(doc.load_string(STR("<node&/>"), parse_minimal).status == status_bad_start_element); + CHECK(doc.load_string(STR("<node& v='1'/>"), parse_minimal).status == status_bad_start_element); } TEST(parse_declaration_cases) { xml_document doc; - CHECK(doc.load(STR("<?xml?><?xmL?><?xMl?><?xML?><?Xml?><?XmL?><?XMl?><?XML?>"), parse_fragment | parse_pi)); + CHECK(doc.load_string(STR("<?xml?><?xmL?><?xMl?><?xML?><?Xml?><?XmL?><?XMl?><?XML?>"), parse_fragment | parse_pi)); CHECK(!doc.first_child()); } TEST(parse_declaration_attr_cases) { xml_document doc; - CHECK(doc.load(STR("<?xml ?><?xmL ?><?xMl ?><?xML ?><?Xml ?><?XmL ?><?XMl ?><?XML ?>"), parse_fragment | parse_pi)); + CHECK(doc.load_string(STR("<?xml ?><?xmL ?><?xMl ?><?xML ?><?Xml ?><?XmL ?><?XMl ?><?XML ?>"), parse_fragment | parse_pi)); CHECK(!doc.first_child()); } @@ -816,10 +816,10 @@ TEST(parse_declaration_skip) { unsigned int flags = flag_sets[i]; - CHECK(doc.load(STR("<?xml?><?xml version='1.0'?>"), flags)); + CHECK(doc.load_string(STR("<?xml?><?xml version='1.0'?>"), flags)); CHECK(!doc.first_child()); - CHECK(doc.load(STR("<?xml <tag/> ?>"), flags)); + CHECK(doc.load_string(STR("<?xml <tag/> ?>"), flags)); CHECK(!doc.first_child()); } } @@ -827,7 +827,7 @@ TEST(parse_declaration_skip) TEST(parse_declaration_parse) { xml_document doc; - CHECK(doc.load(STR("<?xml?><?xml version='1.0'?>"), parse_fragment | parse_declaration)); + CHECK(doc.load_string(STR("<?xml?><?xml version='1.0'?>"), parse_fragment | parse_declaration)); xml_node d1 = doc.first_child(); xml_node d2 = doc.last_child(); @@ -850,23 +850,36 @@ TEST(parse_declaration_error) { unsigned int flags = flag_sets[i]; - CHECK(doc.load(STR("<?xml"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?xml?"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?xml>"), flags).status == status_bad_pi); - CHECK(doc.load(STR("<?xml version='1>"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?xml"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?xml?"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?xml>"), flags).status == status_bad_pi); + CHECK(doc.load_string(STR("<?xml version='1>"), flags).status == status_bad_pi); } - CHECK(doc.load(STR("<?xml version='1?>"), parse_fragment | parse_declaration).status == status_bad_attribute); - CHECK(doc.load(STR("<foo><?xml version='1'?></foo>"), parse_fragment | parse_declaration).status == status_bad_pi); + CHECK(doc.load_string(STR("<?xml version='1?>"), parse_fragment | parse_declaration).status == status_bad_attribute); + CHECK(doc.load_string(STR("<foo><?xml version='1'?></foo>"), parse_fragment | parse_declaration).status == status_bad_pi); } TEST(parse_empty) { xml_document doc; - CHECK(doc.load(STR("")).status == status_no_document_element && !doc.first_child()); - CHECK(doc.load(STR(""), parse_fragment) && !doc.first_child()); - CHECK(doc.load_buffer(NULL, 12).status == status_no_document_element); - CHECK(doc.load_buffer("foo", 0).status == status_no_document_element); + + CHECK(doc.load_string(STR("")).status == status_no_document_element && !doc.first_child()); + CHECK(doc.load_string(STR(""), parse_fragment) && !doc.first_child()); +} + +TEST(parse_load_buffer_null) +{ + xml_document doc; + + CHECK(doc.load_buffer(0, 12).status == status_no_document_element && !doc.first_child()); +} + +TEST(parse_load_buffer_empty) +{ + xml_document doc; + + CHECK(doc.load_buffer("foo", 0).status == status_no_document_element); } TEST(parse_out_of_memory) @@ -874,7 +887,7 @@ TEST(parse_out_of_memory) test_runner::_memory_fail_threshold = 256; xml_document doc; - CHECK(doc.load(STR("<foo a='1'/>")).status == status_out_of_memory); + CHECK(doc.load_string(STR("<foo a='1'/>")).status == status_out_of_memory); CHECK(!doc.first_child()); } @@ -930,7 +943,7 @@ TEST(parse_out_of_memory_halfway_attr) static bool test_offset(const char_t* contents, unsigned int options, pugi::xml_parse_status status, ptrdiff_t offset) { xml_document doc; - xml_parse_result res = doc.load(contents, options); + xml_parse_result res = doc.load_string(contents, options); return res.status == status && res.offset == offset; } @@ -1067,7 +1080,7 @@ TEST(parse_bom_fragment_invalid_utf32) TEST(parse_pcdata_gap_fragment) { xml_document doc; - CHECK(doc.load(STR("a&b"), parse_fragment | parse_escapes)); + CHECK(doc.load_string(STR("a&b"), parse_fragment | parse_escapes)); CHECK_STRING(doc.text().get(), STR("a&b")); } diff --git a/tests/test_parse_doctype.cpp b/tests/test_parse_doctype.cpp index f8619fd..901890c 100644 --- a/tests/test_parse_doctype.cpp +++ b/tests/test_parse_doctype.cpp @@ -20,7 +20,7 @@ static xml_parse_result load_concat(xml_document& doc, const char_t* a, const ch strcat(buffer, c); #endif - return doc.load(buffer, parse_fragment); + return doc.load_string(buffer, parse_fragment); } static bool test_doctype_wf(const char_t* decl) @@ -41,7 +41,7 @@ static bool test_doctype_wf(const char_t* decl) if (!load_concat(doc, STR("<nodea/>"), decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodea /><nodeb />"), STR(""), format_raw)) return false; // check load-store contents preservation - CHECK(doc.load(decl, parse_doctype | parse_fragment)); + CHECK(doc.load_string(decl, parse_doctype | parse_fragment)); CHECK_NODE(doc, decl); return true; @@ -281,8 +281,8 @@ TEST(parse_doctype_xmlconf_oasis_1) // not actually a doctype :) xml_document doc; - CHECK(doc.load(STR("<!--a <!DOCTYPE <?- ]]>-<[ CDATA [ \"- -'- -<doc>--> <!---->"), parse_full | parse_fragment) && doc.first_child().type() == node_comment && doc.last_child().type() == node_comment && doc.first_child().next_sibling() == doc.last_child()); - CHECK(doc.load(STR("<?xmla <!DOCTYPE <[ CDATA [</doc> &a%b&#c?>"), parse_full | parse_fragment) && doc.first_child().type() == node_pi && doc.first_child() == doc.last_child()); + CHECK(doc.load_string(STR("<!--a <!DOCTYPE <?- ]]>-<[ CDATA [ \"- -'- -<doc>--> <!---->"), parse_full | parse_fragment) && doc.first_child().type() == node_comment && doc.last_child().type() == node_comment && doc.first_child().next_sibling() == doc.last_child()); + CHECK(doc.load_string(STR("<?xmla <!DOCTYPE <[ CDATA [</doc> &a%b&#c?>"), parse_full | parse_fragment) && doc.first_child().type() == node_pi && doc.first_child() == doc.last_child()); } TEST(parse_doctype_xmlconf_xmltest_1) @@ -310,15 +310,55 @@ TEST_XML_FLAGS(parse_doctype_value, "<!DOCTYPE doc [ <!ELEMENT doc (#PCDATA)> <! TEST(parse_doctype_error_toplevel) { xml_document doc; - CHECK(doc.load(STR("<node><!DOCTYPE></node>")).status == status_bad_doctype); - CHECK(doc.load(STR("<node><!DOCTYPE></node>"), parse_doctype).status == status_bad_doctype); + CHECK(doc.load_string(STR("<node><!DOCTYPE></node>")).status == status_bad_doctype); + CHECK(doc.load_string(STR("<node><!DOCTYPE></node>"), parse_doctype).status == status_bad_doctype); } TEST(parse_doctype_error_ignore) { xml_document doc; - CHECK(doc.load(STR("<!DOCTYPE root [ <![IGNORE[ ")).status == status_bad_doctype); - CHECK(doc.load(STR("<!DOCTYPE root [ <![IGNORE[ "), parse_doctype).status == status_bad_doctype); - CHECK(doc.load(STR("<!DOCTYPE root [ <![IGNORE[ <![INCLUDE[")).status == status_bad_doctype); - CHECK(doc.load(STR("<!DOCTYPE root [ <![IGNORE[ <![INCLUDE["), parse_doctype).status == status_bad_doctype); + CHECK(doc.load_string(STR("<!DOCTYPE root [ <![IGNORE[ ")).status == status_bad_doctype); + CHECK(doc.load_string(STR("<!DOCTYPE root [ <![IGNORE[ "), parse_doctype).status == status_bad_doctype); + CHECK(doc.load_string(STR("<!DOCTYPE root [ <![IGNORE[ <![INCLUDE[")).status == status_bad_doctype); + CHECK(doc.load_string(STR("<!DOCTYPE root [ <![IGNORE[ <![INCLUDE["), parse_doctype).status == status_bad_doctype); +} + +TEST(parse_doctype_stackless_group) +{ + std::basic_string<char_t> str; + + int count = 100000; + + str += STR("<!DOCTYPE "); + + for (int i = 0; i < count; ++i) + str += STR("<!G "); + + for (int j = 0; j < count; ++j) + str += STR(">"); + + str += STR(">"); + + xml_document doc; + CHECK(doc.load_string(str.c_str(), parse_fragment)); +} + +TEST(parse_doctype_stackless_ignore) +{ + std::basic_string<char_t> str; + + int count = 100000; + + str += STR("<!DOCTYPE "); + + for (int i = 0; i < count; ++i) + str += STR("<![IGNORE[ "); + + for (int j = 0; j < count; ++j) + str += STR("]]>"); + + str += STR(">"); + + xml_document doc; + CHECK(doc.load_string(str.c_str(), parse_fragment)); } diff --git a/tests/test_version.cpp b/tests/test_version.cpp index 622a100..24036fc 100644 --- a/tests/test_version.cpp +++ b/tests/test_version.cpp @@ -1,5 +1,5 @@ #include "../src/pugixml.hpp"
-#if PUGIXML_VERSION != 140
+#if PUGIXML_VERSION != 150
#error Unexpected pugixml version
#endif
diff --git a/tests/test_write.cpp b/tests/test_write.cpp index 8fc88e1..da83745 100644 --- a/tests/test_write.cpp +++ b/tests/test_write.cpp @@ -171,7 +171,7 @@ struct test_writer: xml_writer virtual void write(const void* data, size_t size) { CHECK(size % sizeof(pugi::char_t) == 0); - contents += std::basic_string<pugi::char_t>(static_cast<const pugi::char_t*>(data), static_cast<const pugi::char_t*>(data) + size / sizeof(pugi::char_t)); + contents.append(static_cast<const pugi::char_t*>(data), size / sizeof(pugi::char_t)); } }; @@ -483,7 +483,7 @@ TEST(write_stackless) data += STR("</a>"); xml_document doc; - CHECK(doc.load(data.c_str())); + CHECK(doc.load_string(data.c_str())); CHECK_NODE(doc, data.c_str()); } diff --git a/tests/test_xpath.cpp b/tests/test_xpath.cpp index a65ee37..f5b4c66 100644 --- a/tests/test_xpath.cpp +++ b/tests/test_xpath.cpp @@ -13,7 +13,7 @@ static void load_document_copy(xml_document& doc, const char_t* text) { xml_document source; - CHECK(source.load(text)); + CHECK(source.load_string(text)); doc.append_copy(source.first_child()); } @@ -551,10 +551,10 @@ TEST_XML(xpath_sort_append_buffer, "<node /><node />") TEST(xpath_sort_crossdoc) { xml_document doc1; - CHECK(doc1.load(STR("<node />"))); + CHECK(doc1.load_string(STR("<node />"))); xml_document doc2; - CHECK(doc2.load(STR("<node />"))); + CHECK(doc2.load_string(STR("<node />"))); xpath_node_set ns1 = doc1.select_nodes(STR("*")); CHECK(ns1.size() == 1); @@ -639,9 +639,11 @@ TEST(xpath_allocate_string_out_of_memory) #else try { + #ifndef __DMC__ // DigitalMars exception handling crashes instead of catching the exception... xpath_query q(query.c_str()); CHECK_FORCE_FAIL("Expected out of memory exception"); + #endif } catch (const std::bad_alloc&) { diff --git a/tests/test_xpath_functions.cpp b/tests/test_xpath_functions.cpp index 678bc2e..eb43bb5 100644 --- a/tests/test_xpath_functions.cpp +++ b/tests/test_xpath_functions.cpp @@ -570,6 +570,14 @@ TEST(xpath_string_translate_table) CHECK_XPATH_STRING(c, STR("translate('abcde', 'abcd', concat('ABC', 'D'))"), STR("ABCDe")); } +TEST(xpath_string_translate_remove) +{ + xml_node c; + + CHECK_XPATH_STRING(c, STR("translate('000000755', '0', '')"), STR("755")); + CHECK_XPATH_STRING(c, STR("translate('000000755', concat('0', ''), '')"), STR("755")); +} + TEST_XML(xpath_nodeset_last, "<node><c1/><c1/><c2/><c3/><c3/><c3/><c3/></node>") { xml_node n = doc.child(STR("node")); diff --git a/tests/test_xpath_operators.cpp b/tests/test_xpath_operators.cpp index 57e3755..450af5d 100644 --- a/tests/test_xpath_operators.cpp +++ b/tests/test_xpath_operators.cpp @@ -492,6 +492,7 @@ TEST(xpath_operators_mod) CHECK_XPATH_NUMBER(c, STR("-5 mod 3"), -2); CHECK_XPATH_NUMBER(c, STR("-5 mod -3"), -2); +#if !defined(__BORLANDC__) // If either operand is NaN, the result is NaN CHECK_XPATH_NUMBER_NAN(c, STR("(0 div 0) mod 3")); CHECK_XPATH_NUMBER_NAN(c, STR("3 mod (0 div 0)")); @@ -505,14 +506,17 @@ TEST(xpath_operators_mod) CHECK_XPATH_NUMBER_NAN(c, STR("-1 mod 0")); CHECK_XPATH_NUMBER_NAN(c, STR("(1 div 0) mod 0")); CHECK_XPATH_NUMBER_NAN(c, STR("(-1 div 0) mod 0")); +#endif // If the dividend is finite and the divisor is an infinity, the result equals the dividend +#if !defined(_MSC_VER) && !defined(__MINGW32__) CHECK_XPATH_NUMBER(c, STR("1 mod (1 div 0)"), 1); CHECK_XPATH_NUMBER(c, STR("1 mod (-1 div 0)"), 1); CHECK_XPATH_NUMBER(c, STR("-1 mod (1 div 0)"), -1); CHECK_XPATH_NUMBER(c, STR("0 mod (1 div 0)"), 0); CHECK_XPATH_NUMBER(c, STR("0 mod (-1 div 0)"), 0); CHECK_XPATH_NUMBER(c, STR("100000 mod (1 div 0)"), 100000); +#endif // If the dividend is a zero and the divisor is finite, the result equals the dividend. CHECK_XPATH_NUMBER(c, STR("0 mod 1000000"), 0); diff --git a/tests/test_xpath_paths.cpp b/tests/test_xpath_paths.cpp index e51a395..69215d8 100644 --- a/tests/test_xpath_paths.cpp +++ b/tests/test_xpath_paths.cpp @@ -460,7 +460,10 @@ TEST_XML(xpath_paths_predicate_number_out_of_range, "<node><chapter/><chapter/>< CHECK_XPATH_NODESET(n, STR("following-sibling::chapter[-1 div 0]")); CHECK_XPATH_NODESET(n, STR("following-sibling::chapter[1000000000000]")); CHECK_XPATH_NODESET(n, STR("following-sibling::chapter[1 div 0]")); + +#ifndef MSVC6_NAN_BUG CHECK_XPATH_NODESET(n, STR("following-sibling::chapter[0 div 0]")); +#endif } TEST_XML(xpath_paths_predicate_constant_boolean, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>") @@ -480,7 +483,10 @@ TEST_XML(xpath_paths_predicate_position_eq, "<node><chapter/><chapter/><chapter> CHECK_XPATH_NODESET(doc, STR("node/chapter[position()=1]")) % 3; CHECK_XPATH_NODESET(doc, STR("node/chapter[position()=2+2]")) % 7; CHECK_XPATH_NODESET(doc, STR("node/chapter[position()=last()]")) % 8; + +#ifndef MSVC6_NAN_BUG CHECK_XPATH_NODESET(doc, STR("node/chapter[position()=string()]")) % 5; +#endif } TEST_XML(xpath_paths_predicate_several, "<node><employee/><employee secretary=''/><employee assistant=''/><employee secretary='' assistant=''/><employee assistant='' secretary=''/></node>") diff --git a/tests/writer_string.cpp b/tests/writer_string.cpp index a09678b..661c792 100644 --- a/tests/writer_string.cpp +++ b/tests/writer_string.cpp @@ -15,7 +15,7 @@ static bool test_narrow(const std::string& result, const char* expected, size_t void xml_writer_string::write(const void* data, size_t size) { - contents += std::string(static_cast<const char*>(data), size); + contents.append(static_cast<const char*>(data), size); } std::string xml_writer_string::as_narrow() const |