From: <vac...@us...> - 2009-01-26 17:00:21
|
Revision: 130 http://xmlwrapp.svn.sourceforge.net/xmlwrapp/?rev=130&view=rev Author: vaclavslavik Date: 2009-01-26 17:00:08 +0000 (Mon, 26 Jan 2009) Log Message: ----------- added xml::node::elements() methods for efficient iteration over child elements Modified Paths: -------------- trunk/NEWS trunk/docs/manual/node.doxygen trunk/include/Makefile.am trunk/include/xmlwrapp/node.h trunk/include/xmlwrapp/xmlwrapp.h trunk/platform/Win32/xmlwrapp.dsp trunk/src/Makefile.am trunk/src/libxml/node.cxx trunk/src/libxml/node_iterator.cxx trunk/src/libxml/node_iterator.h trunk/tests/node/Makefile.am trunk/tests/node/data/02.xml trunk/tests/node/runtest.pl Added Paths: ----------- trunk/include/xmlwrapp/nodes_view.h trunk/src/libxml/nodes_view.cxx trunk/tests/node/data/02e.out trunk/tests/node/data/02f.out trunk/tests/node/data/02g.out trunk/tests/node/data/02h.out trunk/tests/node/test_node-02e.cxx trunk/tests/node/test_node-02f.cxx trunk/tests/node/test_node-02g.cxx trunk/tests/node/test_node-02h.cxx Property Changed: ---------------- trunk/tests/node/ Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/NEWS 2009-01-26 17:00:08 UTC (rev 130) @@ -32,6 +32,9 @@ Improved iterators performance (only if Boost.Pool is available). + Added xml::node::elements() methods for efficient iteration over child + elements. In most cases, this is a better alternative to find(). + Version 0.5.1 Various compilation fixes. Modified: trunk/docs/manual/node.doxygen =================================================================== --- trunk/docs/manual/node.doxygen 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/docs/manual/node.doxygen 2009-01-26 17:00:08 UTC (rev 130) @@ -179,7 +179,42 @@ } @endcode +@subsection node_children_elements Iterating Over Children Elements +If you need to do something with all child element nodes, you can use +xml::node::elements() method to obtain a @em view of child nodes. The view, +implemented by xml::nodes_view and xml::const_nodes_view classes, behaves like +a standard container in that it lets you iterate over the nodes in the usual +way. The difference between the iterator returned by xml::nodes_view::begin() +and the one from xml::node::begin() is that the latter iterates over all child +nodes, whereas the former iterates only over selected elements. + +The usage is similar to iterating over all child nodes: + +@code +xml::node n; +... +xml::nodes_view all(n.elements()); +for (xml::nodes_view::iterator i = all.begin()); i != all.end(); ++i) +{ + do_something_with_child(*i); +} +@endcode + +Similarly, you can iterate over all child elements with given name using +the xml::node::elements(const char*) method: + +@code +xml::node n; +... +xml::nodes_view persons(n.elements("person")); +for (xml::nodes_view::iterator i = all.begin()); i != all.end(); ++i) +{ + do_something_with_person_child(*i); +} +@endcode + + @section node_add Adding Children There are two ways of adding a child to a Modified: trunk/include/Makefile.am =================================================================== --- trunk/include/Makefile.am 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/include/Makefile.am 2009-01-26 17:00:08 UTC (rev 130) @@ -7,6 +7,7 @@ xmlwrapp/event_parser.h \ xmlwrapp/init.h \ xmlwrapp/node.h \ + xmlwrapp/nodes_view.h \ xmlwrapp/tree_parser.h \ xmlwrapp/xmlwrapp.h Modified: trunk/include/xmlwrapp/node.h =================================================================== --- trunk/include/xmlwrapp/node.h 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/include/xmlwrapp/node.h 2009-01-26 17:00:08 UTC (rev 130) @@ -53,16 +53,18 @@ // forward declarations class document; class attributes; +class nodes_view; +class const_nodes_view; namespace impl { class node_iterator; +class iter_advance_functor; struct node_impl; struct doc_impl; struct nipimpl; struct node_cmp; } - /** * The xml::node class is used to hold information about one XML node. This * includes the name of the node, the namespace of the node and attributes @@ -620,6 +622,8 @@ * @return An iterator that points to the node if found. * @return An end() iterator if the node was not found. * @author Peter Jones + * + * @see elements(const char*), find(const char*, iterator) **/ //#################################################################### iterator find (const char *name); @@ -638,6 +642,8 @@ * @return A const_iterator that points to the node if found. * @return An end() const_iterator if the node was not found. * @author Peter Jones + * + * @see elements(const char*) const, find(const char*, const_iterator) const **/ //#################################################################### const_iterator find (const char *name) const; @@ -658,6 +664,8 @@ * @return An iterator that points to the node if found. * @return An end() iterator if the node was not found. * @author Peter Jones + * + * @see elements(const char*) **/ //#################################################################### iterator find (const char *name, iterator start); @@ -670,7 +678,7 @@ * * This function should be given a const_iterator to one of this node's * children. The search will begin with that node and continue with all - * its sibliings. This function will not recurse down the tree, it only + * its siblings. This function will not recurse down the tree, it only * searches in one level. * * @param name The name of the node you want to find. @@ -678,10 +686,98 @@ * @return A const_iterator that points to the node if found. * @return An end() const_iterator if the node was not found. * @author Peter Jones + * + * @see elements(const char*) const **/ //#################################################################### const_iterator find (const char *name, const_iterator start) const; + /** + * Returns view of child nodes of type type_element. If no such node + * can be found, returns empty view. + * + * Example: + * @code + * xml::nodes_view view(root.elements()); + * for (xml::nodes_view::iterator i = view.begin(); i != view.end(); ++i) + * { + * ... + * } + * @endcode + * + * @return View with all child elements or empty view if there aren't any. + * @author Vaclav Slavik + * @since 0.6.0 + * + * @see nodes_view + **/ + nodes_view elements(); + + /** + * Returns view of child nodes of type type_element. If no such node + * can be found, returns empty view. + * + * Example: + * @code + * xml::const_nodes_view view(root.elements()); + * for (xml::const_nodes_view::const_iterator i = view.begin(); + * i != view.end(); + * ++i) + * { + * ... + * } + * @endcode + * + * @return View with all child elements or empty view if there aren't any. + * @author Vaclav Slavik + * @since 0.6.0 + * + * @see const_nodes_view + **/ + const_nodes_view elements() const; + + /** + * Returns view of child nodes of type type_element with name @a name. + * If no such node can be found, returns empty view. + * + * Example: + * @code + * xml::nodes_view persons(root.elements("person")); + * for (xml::nodes_view::iterator i = view.begin(); i != view.end(); ++i) + * { + * ... + * } + * @endcode + * + * @param name Name of the elements to return. + * @return View that contains only elements @a name. + * @author Vaclav Slavik + * @since 0.6.0 + **/ + nodes_view elements(const char *name); + + /** + * Returns view of child nodes of type type_element with name @a name. + * If no such node can be found, returns empty view. + * + * Example: + * @code + * xml::const_nodes_view persons(root.elements("person")); + * for (xml::const_nodes_view::const_iterator i = view.begin(); + * i != view.end(); + * ++i) + * { + * ... + * } + * @endcode + * + * @param name Name of the elements to return. + * @return View that contains only elements @a name. + * @author Vaclav Slavik + * @since 0.6.0 + **/ + const_nodes_view elements(const char *name) const; + //#################################################################### /** * Insert a new child node. The new node will be inserted at the end of Added: trunk/include/xmlwrapp/nodes_view.h =================================================================== --- trunk/include/xmlwrapp/nodes_view.h (rev 0) +++ trunk/include/xmlwrapp/nodes_view.h 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2009 Vaclav Slavik <vs...@fa...> + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of the Author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** @file + * This file contains the definition of the xml::nodes_view and + * xml::const_nodes_view classes. +**/ + +#ifndef _xmlwrapp_nodes_view_h_ +#define _xmlwrapp_nodes_view_h_ + +// xmlwrapp includes +#include "xmlwrapp/init.h" + +// standard includes +#include <iterator> + +namespace xml +{ + +class node; +class const_nodes_view; + +namespace impl +{ +class nipimpl; +class iter_advance_functor; +} + +/** + * This class implements a view of XML nodes. A @em view is a container-like + * class that only allows access to a subset of xml::node's child nodes. The + * exact content depends on how the view was obtained; typical uses are + * e.g. a view of all element children or all elements with a given name. + * + * The nodes_view class implements the same container interface that xml::node + * does: it has begin() and end() methods. + * + * @author Vaclav Slavik + * @since 0.6.0 + * + * @see xml::node::elements(), xml::node::elements(const char*) +**/ +class nodes_view +{ +public: + nodes_view() : data_begin_(0), advance_func_(0) {} + nodes_view(const nodes_view& other); + ~nodes_view(); + + nodes_view& operator=(const nodes_view& other); + + /** + * The iterator provides a way to access nodes in the view + * similar to a standard C++ container. + * + * @see xml::node::iterator + **/ + class iterator + { + public: + typedef node value_type; + typedef int difference_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::forward_iterator_tag iterator_category; + + iterator(); + iterator(const iterator& other); + iterator& operator=(const iterator& other); + ~iterator(); + + reference operator*() const; + pointer operator->() const; + + iterator& operator++(); + iterator operator++(int); + + bool operator==(const iterator& other) const; + bool operator!=(const iterator& other) const { return !(*this == other); } + + private: + explicit iterator(void *data, impl::iter_advance_functor *advance_func); + void swap(iterator& other); + + impl::nipimpl *pimpl_; + // function for advancing the iterator (note that it is "owned" by the + // parent view object, so we don't have to care about its reference + // count here) + impl::iter_advance_functor *advance_func_; + + friend class nodes_view; + }; + + /** + * The const_iterator provides a way to access nodes in the view + * similar to a standard C++ container. The nodes that are pointed to by + * the iterator cannot be changed. + * + * @see xml::node::const_iterator + **/ + class const_iterator + { + public: + typedef const node value_type; + typedef int difference_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::forward_iterator_tag iterator_category; + + const_iterator(); + const_iterator(const const_iterator& other); + const_iterator(const iterator& other); + const_iterator& operator=(const const_iterator& other); + const_iterator& operator=(const iterator& other); + ~const_iterator(); + + reference operator*() const; + pointer operator->() const; + + const_iterator& operator++(); + const_iterator operator++(int); + + bool operator==(const const_iterator& other) const; + bool operator!=(const const_iterator& other) const { return !(*this == other); } + + private: + explicit const_iterator(void *data, impl::iter_advance_functor *advance_func); + void swap(const_iterator& other); + + impl::nipimpl *pimpl_; + // function for advancing the iterator (note that it is "owned" by the + // parent view object, so we don't have to care about its reference + // count here) + impl::iter_advance_functor *advance_func_; + + friend class const_nodes_view; + friend class nodes_view; + }; + + /** + * Get an iterator that points to the beginning of this node's + * children. + * + * @return An iterator that points to the beginning of the children. + **/ + iterator begin() { return iterator(data_begin_, advance_func_); } + + /** + * Get an iterator that points to the beginning of this node's + * children. + * + * @return An iterator that points to the beginning of the children. + **/ + const_iterator begin() const { return const_iterator(data_begin_, advance_func_); } + + /** + * Get an iterator that points one past the last child for this node. + * + * @return A "one past the end" iterator. + **/ + iterator end() { return iterator(); } + + /** + * Get an iterator that points one past the last child for this node. + * + * @return A "one past the end" iterator. + **/ + const_iterator end() const { return const_iterator(); } + + /// Is the view empty? + bool empty() const { return !data_begin_; } + +private: + explicit nodes_view(void *data_begin, impl::iter_advance_functor *advance_func) + : data_begin_(data_begin), advance_func_(advance_func) {} + + // begin iterator + void *data_begin_; + // function for advancing the iterator (owned by the view object) + impl::iter_advance_functor *advance_func_; + + friend class node; + friend class const_nodes_view; +}; + + +/** + * This class implements a @em read-only view of XML nodes. The only difference + * from xml::nodes_view is that it doesn't allow modifications of the nodes, + * it is otherwise identical. + * + * @see nodes_view + * + * @author Vaclav Slavik + * @since 0.6.0 +**/ +class const_nodes_view +{ +public: + const_nodes_view() : data_begin_(0), advance_func_(0) {} + const_nodes_view(const const_nodes_view& other); + const_nodes_view(const nodes_view& other); + ~const_nodes_view(); + + const_nodes_view& operator=(const const_nodes_view& other); + const_nodes_view& operator=(const nodes_view& other); + + typedef nodes_view::const_iterator iterator; + typedef nodes_view::const_iterator const_iterator; + + /** + * Get an iterator that points to the beginning of this node's + * children. + * + * @return An iterator that points to the beginning of the children. + **/ + const_iterator begin() const + { return const_iterator(data_begin_, advance_func_); } + + /** + * Get an iterator that points one past the last child for this node. + * + * @return A "one past the end" iterator. + **/ + const_iterator end() const { return const_iterator(); } + + /// Is the view empty? + bool empty() const { return !data_begin_; } + +private: + explicit const_nodes_view(void *data_begin, impl::iter_advance_functor *advance_func) + : data_begin_(data_begin), advance_func_(advance_func) {} + + // begin iterator + void *data_begin_; + // function for advancing the iterator (owned by the view object) + impl::iter_advance_functor *advance_func_; + + friend class node; +}; + +} // end xml namespace + +#endif // _xmlwrapp_nodes_view_h_ Property changes on: trunk/include/xmlwrapp/nodes_view.h ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + native Modified: trunk/include/xmlwrapp/xmlwrapp.h =================================================================== --- trunk/include/xmlwrapp/xmlwrapp.h 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/include/xmlwrapp/xmlwrapp.h 2009-01-26 17:00:08 UTC (rev 130) @@ -34,6 +34,7 @@ #define _xmlwrapp_xmlwrapp_h_ #include "xmlwrapp/init.h" +#include "xmlwrapp/nodes_view.h" #include "xmlwrapp/node.h" #include "xmlwrapp/attributes.h" #include "xmlwrapp/document.h" Modified: trunk/platform/Win32/xmlwrapp.dsp =================================================================== --- trunk/platform/Win32/xmlwrapp.dsp 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/platform/Win32/xmlwrapp.dsp 2009-01-26 17:00:08 UTC (rev 130) @@ -113,6 +113,10 @@ # End Source File # Begin Source File +SOURCE=..\..\src\libxml\nodes_view.cxx +# End Source File +# Begin Source File + SOURCE=..\..\src\libxml\node_iterator.cxx # End Source File # Begin Source File @@ -153,6 +157,10 @@ # End Source File # Begin Source File +SOURCE=..\..\include\xmlwrapp\nodes_view.h +# End Source File +# Begin Source File + SOURCE=..\..\include\xmlwrapp\tree_parser.h # End Source File # Begin Source File Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/src/Makefile.am 2009-01-26 17:00:08 UTC (rev 130) @@ -21,6 +21,7 @@ libxml/event_parser.cxx \ libxml/init.cxx \ libxml/node.cxx \ + libxml/nodes_view.cxx \ libxml/node_iterator.cxx \ libxml/node_iterator.h \ libxml/node_manip.cxx \ Modified: trunk/src/libxml/node.cxx =================================================================== --- trunk/src/libxml/node.cxx 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/src/libxml/node.cxx 2009-01-26 17:00:08 UTC (rev 130) @@ -36,11 +36,13 @@ // xmlwrapp includes #include "xmlwrapp/node.h" +#include "xmlwrapp/nodes_view.h" #include "xmlwrapp/attributes.h" #include "utility.h" #include "ait_impl.h" #include "node_manip.h" #include "pimpl_base.h" +#include "node_iterator.h" // standard includes #include <cstring> @@ -175,8 +177,41 @@ xmlNodePtr parent_; }; - // a node finder - xmlNodePtr find_node(const char *name, xmlNodePtr first); + // an element node finder + xmlNodePtr find_element(const char *name, xmlNodePtr first) { + while (first != 0) { + if (first->type == XML_ELEMENT_NODE && xmlStrcmp(first->name, reinterpret_cast<const xmlChar*>(name)) == 0) return first; + first = first->next; + } + + return 0; + } + + xmlNodePtr find_element(xmlNodePtr first) { + while (first != 0) { + if (first->type == XML_ELEMENT_NODE) return first; + first = first->next; + } + + return 0; + } + + class next_element_functor : public iter_advance_functor + { + public: + virtual xmlNodePtr operator()(xmlNodePtr node) const + { return find_element(node->next); } + }; + + class next_named_element_functor : public iter_advance_functor + { + public: + next_named_element_functor(const char *name) : name_(name) {} + virtual xmlNodePtr operator()(xmlNodePtr node) const + { return find_element(name_.c_str(), node->next); } + private: + std::string name_; + }; } //#################################################################### xml::node::node (int) { @@ -411,28 +446,65 @@ } //#################################################################### xml::node::iterator xml::node::find (const char *name) { - xmlNodePtr found = find_node(name, pimpl_->xmlnode_->children); + xmlNodePtr found = find_element(name, pimpl_->xmlnode_->children); if (found) return iterator(found); return end(); } //#################################################################### xml::node::const_iterator xml::node::find (const char *name) const { - xmlNodePtr found = find_node(name, pimpl_->xmlnode_->children); + xmlNodePtr found = find_element(name, pimpl_->xmlnode_->children); if (found) return const_iterator(found); return end(); } //#################################################################### xml::node::iterator xml::node::find (const char *name, iterator start) { xmlNodePtr n = static_cast<xmlNodePtr>(start.get_raw_node()); - if ( (n = find_node(name, n))) return iterator(n); + if ( (n = find_element(name, n))) return iterator(n); return end(); } //#################################################################### xml::node::const_iterator xml::node::find (const char *name, const_iterator start) const { xmlNodePtr n = static_cast<xmlNodePtr>(start.get_raw_node()); - if ( (n = find_node(name, n))) return const_iterator(n); + if ( (n = find_element(name, n))) return const_iterator(n); return end(); } + +xml::nodes_view xml::node::elements() +{ + return nodes_view + ( + find_element(pimpl_->xmlnode_->children), + new next_element_functor + ); +} + +xml::const_nodes_view xml::node::elements() const +{ + return const_nodes_view + ( + find_element(pimpl_->xmlnode_->children), + new next_element_functor + ); +} + +xml::nodes_view xml::node::elements(const char *name) +{ + return nodes_view + ( + find_element(name, pimpl_->xmlnode_->children), + new next_named_element_functor(name) + ); +} + +xml::const_nodes_view xml::node::elements(const char *name) const +{ + return const_nodes_view + ( + find_element(name, pimpl_->xmlnode_->children), + new next_named_element_functor(name) + ); +} + //#################################################################### xml::node::iterator xml::node::insert (const node &n) { return iterator(xml::impl::node_insert(pimpl_->xmlnode_, 0, n.pimpl_->xmlnode_)); @@ -522,17 +594,6 @@ if (xml_string_length) xml.assign(helper.get(), xml_string_length); } //#################################################################### -namespace { - xmlNodePtr find_node(const char *name, xmlNodePtr first) { - while (first != 0) { - if (first->type == XML_ELEMENT_NODE && xmlStrcmp(first->name, reinterpret_cast<const xmlChar*>(name)) == 0) return first; - first = first->next; - } - - return 0; - } -} -//#################################################################### namespace xml { std::ostream& operator<< (std::ostream &stream, const xml::node &n) { std::string xmldata; Modified: trunk/src/libxml/node_iterator.cxx =================================================================== --- trunk/src/libxml/node_iterator.cxx 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/src/libxml/node_iterator.cxx 2009-01-26 17:00:08 UTC (rev 130) @@ -40,6 +40,7 @@ // xmlwrapp includes #include "xmlwrapp/node.h" +#include "xmlwrapp/nodes_view.h" // standard includes #include <algorithm> @@ -69,11 +70,6 @@ return &fake_node_; } //#################################################################### -xml::impl::node_iterator& xml::impl::node_iterator::operator++ (void) { - node_ = node_->next; - return *this; -} -//#################################################################### /* * xml::node::iterator wrapper iterator class. @@ -115,7 +111,7 @@ } //#################################################################### xml::node::iterator& xml::node::iterator::operator++ (void) { - ++(pimpl_->it); + pimpl_->it.advance(); return *this; } //#################################################################### @@ -174,7 +170,7 @@ } //#################################################################### xml::node::const_iterator& xml::node::const_iterator::operator++ (void) { - ++(pimpl_->it); + pimpl_->it.advance(); return *this; } //#################################################################### @@ -217,3 +213,169 @@ } } //#################################################################### + + +namespace xml +{ + +// ------------------------------------------------------------------------ +// xml::nodes_view::iterator +// ------------------------------------------------------------------------ + +nodes_view::iterator::iterator() +{ + pimpl_ = new nipimpl; + advance_func_ = 0; +} + +nodes_view::iterator::iterator(const iterator& other) +{ + pimpl_ = new nipimpl(*(other.pimpl_)); + advance_func_ = other.advance_func_; +} + +nodes_view::iterator& +nodes_view::iterator::operator=(const iterator& other) +{ + iterator tmp(other); + swap(tmp); + return *this; +} + +nodes_view::iterator::~iterator() +{ + delete pimpl_; +} + +nodes_view::iterator::reference +nodes_view::iterator::operator*() const +{ + return *(pimpl_->it.get()); +} + +nodes_view::iterator::pointer +nodes_view::iterator::operator->() const +{ + return pimpl_->it.get(); +} + +nodes_view::iterator& nodes_view::iterator::operator++() +{ + assert( advance_func_ ); + pimpl_->it.advance(*advance_func_); + return *this; +} + +nodes_view::iterator nodes_view::iterator::operator++(int) +{ + iterator tmp(*this); + ++(*this); + return tmp; +} + +bool nodes_view::iterator::operator==(const iterator& other) const +{ + return pimpl_->it == other.pimpl_->it; +} + +nodes_view::iterator::iterator(void *data, impl::iter_advance_functor *advance_func) +{ + assert( advance_func ); + pimpl_ = new nipimpl(static_cast<xmlNodePtr>(data)); + advance_func_ = advance_func; +} + +void nodes_view::iterator::swap(iterator& other) +{ + std::swap(pimpl_, other.pimpl_); + std::swap(advance_func_, other.advance_func_); +} + +// ------------------------------------------------------------------------ +// xml::nodes_view::const_iterator +// ------------------------------------------------------------------------ + +nodes_view::const_iterator::const_iterator() +{ + pimpl_ = new nipimpl; + advance_func_ = 0; +} + +nodes_view::const_iterator::const_iterator(const const_iterator& other) +{ + pimpl_ = new nipimpl(*(other.pimpl_)); + advance_func_ = other.advance_func_; +} + +nodes_view::const_iterator::const_iterator(const iterator& other) +{ + pimpl_ = new nipimpl(*(other.pimpl_)); + advance_func_ = other.advance_func_; +} + +nodes_view::const_iterator& +nodes_view::const_iterator::operator=(const const_iterator& other) +{ + const_iterator tmp(other); + swap(tmp); + return *this; +} + +nodes_view::const_iterator& +nodes_view::const_iterator::operator=(const iterator& other) +{ + const_iterator tmp(other); + swap(tmp); + return *this; +} + +nodes_view::const_iterator::~const_iterator() +{ + delete pimpl_; +} + +nodes_view::const_iterator::reference +nodes_view::const_iterator::operator*() const +{ + return *(pimpl_->it.get()); +} + +nodes_view::const_iterator::pointer +nodes_view::const_iterator::operator->() const +{ + return pimpl_->it.get(); +} + +nodes_view::const_iterator& nodes_view::const_iterator::operator++() +{ + assert( advance_func_ ); + pimpl_->it.advance(*advance_func_); + return *this; +} + +nodes_view::const_iterator nodes_view::const_iterator::operator++(int) +{ + const_iterator tmp(*this); + ++(*this); + return tmp; +} + +bool nodes_view::const_iterator::operator==(const const_iterator& other) const +{ + return pimpl_->it == other.pimpl_->it; +} + +nodes_view::const_iterator::const_iterator(void *data, impl::iter_advance_functor *advance_func) +{ + assert( advance_func ); + pimpl_ = new nipimpl(static_cast<xmlNodePtr>(data)); + advance_func_ = advance_func; +} + +void nodes_view::const_iterator::swap(nodes_view::const_iterator& other) +{ + std::swap(pimpl_, other.pimpl_); + std::swap(advance_func_, other.advance_func_); +} + +} // namespace xml Modified: trunk/src/libxml/node_iterator.h =================================================================== --- trunk/src/libxml/node_iterator.h 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/src/libxml/node_iterator.h 2009-01-26 17:00:08 UTC (rev 130) @@ -47,6 +47,38 @@ namespace impl { +// helper to obtain the next node in "filtering" iterators (as used by +// nodes_view and const_nodes_view) +// +// Note: This class is reference-counted; don't delete instance of it, use +// dec_ref() and inc_ref(). Newly created instance has reference count +// of 1. +class iter_advance_functor +{ +public: + iter_advance_functor() : refcnt_(1) {} + + void inc_ref() + { + refcnt_++; + } + + void dec_ref() + { + if ( --refcnt_ == 0 ) + delete this; + } + + virtual xmlNodePtr operator()(xmlNodePtr node) const = 0; + +protected: + // use inc_ref(), dec_ref() instead of using the dtor explicitly + virtual ~iter_advance_functor() {} + +private: + int refcnt_; +}; + // base iterator class class node_iterator { public: @@ -59,10 +91,12 @@ node* get (void) const; xmlNodePtr get_raw_node (void) { return node_; } - node_iterator& operator++ (void); + void advance() { node_ = node_->next; } + void advance(iter_advance_functor& next) { node_ = next(node_); } friend bool operator== (const node_iterator &lhs, const node_iterator &rhs); + private: mutable node fake_node_; xmlNodePtr node_; Added: trunk/src/libxml/nodes_view.cxx =================================================================== --- trunk/src/libxml/nodes_view.cxx (rev 0) +++ trunk/src/libxml/nodes_view.cxx 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2009 Vaclav Slavik <vs...@fa...> + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of the Author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +// xmlwrapp includes +#include "xmlwrapp/nodes_view.h" + +// definition include +#include "node_iterator.h" +#include "pimpl_base.h" + +namespace xml +{ + +// ------------------------------------------------------------------------ +// xml::const_nodes_view +// ------------------------------------------------------------------------ + +const_nodes_view::const_nodes_view(const const_nodes_view& other) + : data_begin_(other.data_begin_), + advance_func_(other.advance_func_) +{ + if ( advance_func_ ) + advance_func_->inc_ref(); +} + +const_nodes_view::const_nodes_view(const nodes_view& other) + : data_begin_(other.data_begin_), + advance_func_(other.advance_func_) +{ + if ( advance_func_ ) + advance_func_->inc_ref(); +} + +const_nodes_view::~const_nodes_view() +{ + if ( advance_func_ ) + advance_func_->dec_ref(); +} + +const_nodes_view& const_nodes_view::operator=(const const_nodes_view& other) +{ + if ( advance_func_ ) + advance_func_->dec_ref(); + + data_begin_ = other.data_begin_; + advance_func_ = other.advance_func_; + + if ( advance_func_ ) + advance_func_->inc_ref(); + + return *this; +} + +const_nodes_view& const_nodes_view::operator=(const nodes_view& other) +{ + if ( advance_func_ ) + advance_func_->dec_ref(); + + data_begin_ = other.data_begin_; + advance_func_ = other.advance_func_; + + if ( advance_func_ ) + advance_func_->inc_ref(); + + return *this; +} + +// ------------------------------------------------------------------------ +// xml::nodes_view +// ------------------------------------------------------------------------ + +nodes_view::nodes_view(const nodes_view& other) + : data_begin_(other.data_begin_), + advance_func_(other.advance_func_) +{ + if ( advance_func_ ) + advance_func_->inc_ref(); +} + +nodes_view::~nodes_view() +{ + if ( advance_func_ ) + advance_func_->dec_ref(); +} + +nodes_view& nodes_view::operator=(const nodes_view& other) +{ + if ( advance_func_ ) + advance_func_->dec_ref(); + + data_begin_ = other.data_begin_; + advance_func_ = other.advance_func_; + + if ( advance_func_ ) + advance_func_->inc_ref(); + + return *this; +} + +} // namespace xml Property changes on: trunk/tests/node ___________________________________________________________________ Modified: svn:ignore - Makefile Makefile.in .deps .libs test_node-01 test_node-02a test_node-02b test_node-02c test_node-02d test_node-03a test_node-03b test_node-04a test_node-04b test_node-05a test_node-05b test_node-05c test_node-05d test_node-06 test_node-07 test_node-08 test_node-09 test_node-10 test_node-11 test_node-12 test_node-13 test_node-14 + Makefile Makefile.in .deps .libs test_node-01 test_node-02a test_node-02b test_node-02c test_node-02d test_node-02e test_node-02f test_node-02g test_node-02h test_node-03a test_node-03b test_node-04a test_node-04b test_node-05a test_node-05b test_node-05c test_node-05d test_node-06 test_node-07 test_node-08 test_node-09 test_node-10 test_node-11 test_node-12 test_node-13 test_node-14 Modified: trunk/tests/node/Makefile.am =================================================================== --- trunk/tests/node/Makefile.am 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/tests/node/Makefile.am 2009-01-26 17:00:08 UTC (rev 130) @@ -10,6 +10,10 @@ test_node-02b \ test_node-02c \ test_node-02d \ + test_node-02e \ + test_node-02f \ + test_node-02g \ + test_node-02h \ test_node-03a \ test_node-03b \ test_node-04a \ @@ -33,6 +37,10 @@ test_node_02b_SOURCES = test_node-02b.cxx test_node_02c_SOURCES = test_node-02c.cxx test_node_02d_SOURCES = test_node-02d.cxx +test_node_02e_SOURCES = test_node-02e.cxx +test_node_02f_SOURCES = test_node-02f.cxx +test_node_02g_SOURCES = test_node-02g.cxx +test_node_02h_SOURCES = test_node-02h.cxx test_node_03a_SOURCES = test_node-03a.cxx test_node_03b_SOURCES = test_node-03b.cxx test_node_04a_SOURCES = test_node-04a.cxx Modified: trunk/tests/node/data/02.xml =================================================================== --- trunk/tests/node/data/02.xml 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/tests/node/data/02.xml 2009-01-26 17:00:08 UTC (rev 130) @@ -1 +1 @@ -<root><person><name>Peter</name><state>CO</state></person><person><name>Isaac</name><state>CA</state></person><person><name>Albert</name><state>AZ</state></person></root> +<root><person><name>Peter</name><state>CO</state></person><person><name>Isaac</name><state>CA</state></person><unrelated_element/><person><name>Albert</name><state>AZ</state></person></root> Added: trunk/tests/node/data/02e.out =================================================================== --- trunk/tests/node/data/02e.out (rev 0) +++ trunk/tests/node/data/02e.out 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<person> + <name>Peter</name> + <state>CO</state> +</person> +<?xml version="1.0"?> +<person> + <name>Isaac</name> + <state>CA</state> +</person> +<?xml version="1.0"?> +<person> + <name>Albert</name> + <state>AZ</state> +</person> Added: trunk/tests/node/data/02f.out =================================================================== --- trunk/tests/node/data/02f.out (rev 0) +++ trunk/tests/node/data/02f.out 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<person> + <name>Peter</name> + <state>CO</state> +</person> +<?xml version="1.0"?> +<person> + <name>Isaac</name> + <state>CA</state> +</person> +<?xml version="1.0"?> +<person> + <name>Albert</name> + <state>AZ</state> +</person> Added: trunk/tests/node/data/02g.out =================================================================== --- trunk/tests/node/data/02g.out (rev 0) +++ trunk/tests/node/data/02g.out 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<person> + <name>Peter</name> + <state>CO</state> +</person> +<?xml version="1.0"?> +<person> + <name>Isaac</name> + <state>CA</state> +</person> +<?xml version="1.0"?> +<unrelated_element/> +<?xml version="1.0"?> +<person> + <name>Albert</name> + <state>AZ</state> +</person> Added: trunk/tests/node/data/02h.out =================================================================== --- trunk/tests/node/data/02h.out (rev 0) +++ trunk/tests/node/data/02h.out 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<person> + <name>Peter</name> + <state>CO</state> +</person> +<?xml version="1.0"?> +<person> + <name>Isaac</name> + <state>CA</state> +</person> +<?xml version="1.0"?> +<unrelated_element/> +<?xml version="1.0"?> +<person> + <name>Albert</name> + <state>AZ</state> +</person> Modified: trunk/tests/node/runtest.pl =================================================================== --- trunk/tests/node/runtest.pl 2009-01-25 13:42:49 UTC (rev 129) +++ trunk/tests/node/runtest.pl 2009-01-26 17:00:08 UTC (rev 130) @@ -46,6 +46,9 @@ foreach my $i (qw(02a 02b 02c 02d)) { $test->regression("find ($i)", "./test_node-$i data/02.xml", "data/$i.out"); } + foreach my $i (qw(02e 02f 02g 02h)) { + $test->regression("elements ($i)", "./test_node-$i data/02.xml", "data/$i.out"); + } ########################################################################### foreach my $i (qw(03a 03b)) { $test->regression("replace ($i)", "./test_node-$i data/03.xml", "data/$i.out"); Added: trunk/tests/node/test_node-02e.cxx =================================================================== --- trunk/tests/node/test_node-02e.cxx (rev 0) +++ trunk/tests/node/test_node-02e.cxx 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 Vaclav Slavik <vs...@fa...> + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of the Author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * This test checks xml::node::iterator xml::node::elements (const char *name); + */ + +#include <xmlwrapp/xmlwrapp.h> +#include <iostream> +#include <exception> + +int main (int argc, char *argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " xmlfile\n"; + return 1; + } + + try { + xml::tree_parser parser(argv[1]); + + xml::node &root = parser.get_document().get_root_node(); + xml::nodes_view persons(root.elements("person")); + for (xml::nodes_view::const_iterator i = persons.begin(); i != persons.end(); ++i) { + std::cout << *i; + } + } catch (const std::exception &e) { + std::cout << e.what() << std::endl; + return 1; + } + + return 0; +} Added: trunk/tests/node/test_node-02f.cxx =================================================================== --- trunk/tests/node/test_node-02f.cxx (rev 0) +++ trunk/tests/node/test_node-02f.cxx 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008 Vaclav Slavik <vs...@fa...> + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of the Author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * This test checks xml::node::elements (const char *name); + */ + +#include <xmlwrapp/xmlwrapp.h> +#include <iostream> +#include <exception> +#include <cassert> + +int main (int argc, char *argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " xmlfile\n"; + return 1; + } + + try { + xml::tree_parser parser(argv[1]); + + const xml::node &root = parser.get_document().get_root_node(); + xml::const_nodes_view persons(root.elements("person")); + for (xml::const_nodes_view::const_iterator i = persons.begin(); i != persons.end(); ++i) { + std::cout << *i; + } + + // FIXME: make this a proper test after moving to Cppunit or Boost.Unit + xml::const_nodes_view v2(root.elements("nonexistent")); + assert( v2.begin() == v2.end() ); + assert( v2.empty() ); + + } catch (const std::exception &e) { + std::cout << e.what() << std::endl; + return 1; + } + + return 0; +} Added: trunk/tests/node/test_node-02g.cxx =================================================================== --- trunk/tests/node/test_node-02g.cxx (rev 0) +++ trunk/tests/node/test_node-02g.cxx 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 Vaclav Slavik <vs...@fa...> + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of the Author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * This test checks xml::node::iterator xml::node::elements (const char *name); + */ + +#include <xmlwrapp/xmlwrapp.h> +#include <iostream> +#include <exception> + +int main (int argc, char *argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " xmlfile\n"; + return 1; + } + + try { + xml::tree_parser parser(argv[1]); + + xml::node &root = parser.get_document().get_root_node(); + xml::nodes_view all(root.elements()); + for (xml::nodes_view::const_iterator i = all.begin(); i != all.end(); ++i) { + std::cout << *i; + } + } catch (const std::exception &e) { + std::cout << e.what() << std::endl; + return 1; + } + + return 0; +} Added: trunk/tests/node/test_node-02h.cxx =================================================================== --- trunk/tests/node/test_node-02h.cxx (rev 0) +++ trunk/tests/node/test_node-02h.cxx 2009-01-26 17:00:08 UTC (rev 130) @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 Vaclav Slavik <vs...@fa...> + * All Rights Reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of the Author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * This test checks xml::node::elements (const char *name); + */ + +#include <xmlwrapp/xmlwrapp.h> +#include <iostream> +#include <exception> + +int main (int argc, char *argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " xmlfile\n"; + return 1; + } + + try { + xml::tree_parser parser(argv[1]); + + const xml::node &root = parser.get_document().get_root_node(); + xml::const_nodes_view all(root.elements()); + for (xml::const_nodes_view::const_iterator i = all.begin(); i != all.end(); ++i) { + std::cout << *i; + } + } catch (const std::exception &e) { + std::cout << e.what() << std::endl; + return 1; + } + + return 0; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |