xmlwrapp
xmlwrapp/node.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org)
00003  *               2009      Vaclav Slavik <vslavik@gmail.com>
00004  * All Rights Reserved
00005  * 
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  * 3. Neither the name of the Author nor the names of its contributors
00017  *    may be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  * 
00020  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
00021  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00026  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00027  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00028  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00029  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00030  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  */
00033 
00034 /**
00035     @file
00036 
00037     This file contains the definition of the xml::node class.
00038  */
00039 
00040 #ifndef _xmlwrapp_node_h_
00041 #define _xmlwrapp_node_h_
00042 
00043 // xmlwrapp includes
00044 #include "xmlwrapp/init.h"
00045 
00046 // hidden stuff
00047 #include "xmlwrapp/_cbfo.h"
00048 
00049 // standard includes
00050 #include <cstddef>
00051 #include <iosfwd>
00052 #include <string>
00053 
00054 namespace xml
00055 {
00056 
00057 // forward declarations
00058 class document;
00059 class attributes;
00060 class nodes_view;
00061 class const_nodes_view;
00062 
00063 namespace impl
00064 {
00065 class node_iterator;
00066 class iter_advance_functor;
00067 struct node_impl;
00068 struct doc_impl;
00069 struct nipimpl;
00070 struct node_cmp;
00071 }
00072 
00073 /**
00074     The xml::node class is used to hold information about one XML node.
00075 
00076     This includes the name of the node, the namespace of the node and
00077     attributes for the node. It also has an iterator whereby you can get to the
00078     children nodes.
00079 
00080     It should be noted that any member function that returns a const char*
00081     returns a temporary value. The pointer that is returned will change with
00082     ANY operation to the xml::node. If you need the data to stick around a
00083     little longer you should put it inside a std::string.
00084  */
00085 class node
00086 {
00087 public:
00088     /// size type
00089     typedef std::size_t size_type;
00090 
00091     /// enum for the different types of XML nodes
00092     enum node_type
00093     {
00094         type_element,       ///< XML element such as "<chapter/>"
00095         type_text,          ///< Text node
00096         type_cdata,         ///< <![CDATA[text]]>
00097         type_pi,            ///< Processing Instruction
00098         type_comment,       ///< XML comment
00099         type_entity,        ///< Entity as in &amp;amp;
00100         type_entity_ref,    ///< Entity ref
00101         type_xinclude,      ///< <xi:include/> node
00102         type_document,      ///< Document node
00103         type_document_type, ///< DOCTYPE node
00104         type_document_frag, ///< Document Fragment
00105         type_notation,      ///< Notation
00106         type_dtd,           ///< DTD node
00107         type_dtd_element,   ///< DTD <!ELEMENT> node
00108         type_dtd_attribute, ///< DTD <!ATTRLIST> node
00109         type_dtd_entity,    ///< DTD <!ENTITY>
00110         type_dtd_namespace  ///< ?
00111     };
00112 
00113     /**
00114         Helper struct for creating a xml::node of type_cdata.
00115 
00116         @code
00117         xml::node mynode(xml::node::cdata("This is a CDATA section"));
00118         @endcode
00119      */
00120     struct cdata
00121     {
00122         explicit cdata(const char *text) : t(text) {}
00123         const char *t;
00124     };
00125 
00126     /**
00127         Helper struct for creating a xml::node of type_comment.
00128 
00129         @code
00130         xml::node mynode(xml::node::comment("This is an XML comment"));
00131         @endcode
00132      */
00133     struct comment
00134     {
00135         explicit comment (const char *text) : t(text) {}
00136         const char *t;
00137     };
00138 
00139     /**
00140         Helper struct for creating a xml::node of type_pi.
00141 
00142         @code
00143         xml::node mynode(xml::node::pi("xslt", "stylesheet=\"test.xsl\""));
00144         @endcode
00145      */
00146     struct pi
00147     {
00148         explicit pi (const char *name, const char *content = NULL)
00149             : n(name), c(content) {}
00150         const char *n, *c;
00151     };
00152 
00153     /**
00154         Helper struct for creating a xml::node of type_text.
00155 
00156         @code
00157         xml::node mynode(xml::node::text("This is an XML text fragment"));
00158         @endcode
00159      */
00160     struct text
00161     {
00162         explicit text (const char *text) : t(text) {}
00163         const char *t;
00164     };
00165 
00166     /**
00167         Construct a new blank xml::node.
00168      */
00169     node();
00170 
00171     /**
00172         Construct a new xml::node and set the name of the node.
00173 
00174         @param name The name of the new node.
00175      */
00176     explicit node(const char *name);
00177 
00178     /**
00179         Construct a new xml::node given a name and content. The content will
00180         be used to create a new child text node.
00181 
00182         @param name The name of the new element.
00183         @param content The text that will be used to create a child node.
00184      */
00185     node(const char *name, const char *content);
00186 
00187     /**
00188         Construct a new xml::node that is of type_cdata. The cdata_info
00189         parameter should contain the contents of the CDATA section.
00190 
00191         @note Sample Use Example:
00192         @code
00193         xml::node mynode(xml::node::cdata("This is a CDATA section"));
00194         @endcode
00195 
00196         @param cdata_info A cdata struct that tells xml::node what the
00197                           content will be.
00198      */
00199     explicit node(cdata cdata_info);
00200 
00201     /**
00202         Construct a new xml::node that is of type_comment. The comment_info
00203         parameter should contain the contents of the XML comment.
00204 
00205         @note Sample Use Example:
00206         @code
00207         xml::node mynode(xml::node::comment("This is an XML comment"));
00208         @endcode
00209 
00210         @param comment_info A comment struct that tells xml::node what the comment will be.
00211      */
00212     explicit node(comment comment_info);
00213 
00214     /**
00215         Construct a new xml::node that is of type_pi. The pi_info parameter
00216         should contain the name of the XML processing instruction (PI), and
00217         optionally, the contents of the XML PI.
00218 
00219         @note Sample Use Example:
00220         @code
00221         xml::node mynode(xml::node::pi("xslt", "stylesheet=\"test.xsl\""));
00222         @endcode
00223 
00224         @param pi_info A pi struct that tells xml::node what the name and contents of the XML PI are.
00225      */
00226     explicit node(pi pi_info);
00227 
00228     /**
00229         Construct a new xml::node that is of type_text. The text_info
00230         parameter should contain the text.
00231 
00232         @note Sample Use Example:
00233         @code
00234         xml::node mynode(xml::node::text("This is XML text"));
00235         @endcode
00236 
00237         @param text_info A text struct that tells xml::node what the text will be.
00238      */
00239     explicit node(text text_info);
00240 
00241     /**
00242         Construct a new xml::node by copying another xml::node.
00243 
00244         @param other The other node to copy.
00245      */
00246     node(const node& other);
00247 
00248     /**
00249         Make this node equal to some other node via assignment.
00250 
00251         @param other The other node to copy.
00252         @return A reference to this node.
00253      */
00254     node& operator=(const node& other);
00255 
00256     /**
00257         Class destructor
00258      */
00259     ~node();
00260 
00261     /**
00262         Set the name of this xml::node.
00263 
00264         @param name The new name for this xml::node.
00265      */
00266     void set_name(const char *name);
00267 
00268     /**
00269         Get the name of this xml::node.
00270 
00271         This function may change in the future to return std::string.
00272         Feedback is welcome.
00273 
00274         @return The name of this node.
00275      */
00276     const char* get_name() const;
00277 
00278     /**
00279         Set the content of a node. If this node is an element node, this
00280         function will remove all of its children nodes and replace them
00281         with one text node set to the given string.
00282 
00283         @param content The content of the text node.
00284 
00285         @note @a content is supposed to be a piece of XML CDATA, so it allows
00286               entity references, but XML special chars need to be escaped
00287               first. In particular, the '&' character @em must be escaped
00288               as "&amp;" unless it's part of entity reference. Not escaping
00289               @a content may result in truncation of data.
00290      */
00291     void set_content(const char *content);
00292 
00293     /**
00294         Get the content for this text node. If this node is not a text node
00295         but it has children nodes that are text nodes, the contents of those
00296         child nodes will be returned. If there is no content or these
00297         conditions do not apply, zero will be returned.
00298 
00299         This function may change in the future to return std::string.
00300         Feedback is welcome.
00301 
00302         @return The content or 0.
00303      */
00304     const char* get_content() const;
00305 
00306     /**
00307         Get this node's "type". You can use that information to know what you
00308         can and cannot do with it.
00309 
00310         @return The node's type.
00311      */
00312     node_type get_type() const;
00313 
00314     /**
00315         Get the list of attributes. You can use the returned object to get
00316         and set the attributes for this node. Make sure you use a reference
00317         to this returned object, to prevent a copy.
00318 
00319         @return The xml::attributes object for this node.
00320      */
00321     xml::attributes& get_attributes();
00322 
00323     /**
00324         Get the list of attributes. You can use the returned object to get
00325         the attributes for this node. Make sure you use a reference to this
00326         returned object, to prevent a copy.
00327 
00328         @return The xml::attributes object for this node.
00329      */
00330     const xml::attributes& get_attributes() const;
00331 
00332     /**
00333         Get the namespace of this xml::node.
00334 
00335         @return The namespace of this node or NULL if no namespace is
00336                 associated.
00337         @since  0.6.0
00338      */
00339     const char* get_namespace() const;
00340 
00341     /**
00342         Find out if this node is a text node or sometiming like a text node,
00343         CDATA for example.
00344 
00345         @return True if this node is a text node; false otherwise.
00346      */
00347     bool is_text() const;
00348 
00349     /**
00350         Add a child xml::node to this node.
00351 
00352         @param child The child xml::node to add.
00353      */
00354     void push_back(const node& child);
00355 
00356     /**
00357         Swap this node with another one.
00358 
00359         @param other The other node to swap with.
00360      */
00361     void swap(node& other);
00362 
00363     class const_iterator; // forward declaration
00364 
00365     /**
00366         The xml::node::iterator provides a way to access children nodes
00367         similar to a standard C++ container. The nodes that are pointed to by
00368         the iterator can be changed.
00369      */
00370     class iterator
00371     {
00372     public:
00373         typedef node value_type;
00374         typedef int difference_type;
00375         typedef value_type* pointer;
00376         typedef value_type& reference;
00377         typedef std::forward_iterator_tag iterator_category;
00378 
00379         iterator() : pimpl_(0) {}
00380         iterator(const iterator& other);
00381         iterator& operator=(const iterator& other);
00382         ~iterator();
00383 
00384         reference operator* () const;
00385         pointer   operator->() const;
00386 
00387         /// prefix increment
00388         iterator& operator++();
00389 
00390         /// postfix increment (avoid if possible for better performance)
00391         iterator  operator++ (int);
00392 
00393         bool operator==(const iterator& other) const
00394             { return get_raw_node() == other.get_raw_node(); }
00395         bool operator!=(const iterator& other) const
00396             { return !(*this == other); }
00397 
00398     private:
00399         impl::nipimpl *pimpl_;
00400 
00401         explicit iterator (void *data);
00402         void* get_raw_node() const;
00403         void swap (iterator &other);
00404 
00405         friend class node;
00406         friend class document;
00407         friend class const_iterator;
00408     };
00409 
00410     /**
00411         The xml::node::const_iterator provides a way to access children nodes
00412         similar to a standard C++ container. The nodes that are pointed to by
00413         the const_iterator cannot be changed.
00414      */
00415     class const_iterator
00416     {
00417     public:
00418         typedef const node value_type;
00419         typedef int difference_type;
00420         typedef value_type* pointer;
00421         typedef value_type& reference;
00422         typedef std::forward_iterator_tag iterator_category;
00423 
00424         const_iterator() : pimpl_(0) {}
00425         const_iterator(const const_iterator &other);
00426         const_iterator(const iterator &other);
00427         const_iterator& operator=(const const_iterator& other);
00428         ~const_iterator();
00429 
00430         reference operator* () const;
00431         pointer   operator->() const;
00432 
00433         /// prefix increment
00434         const_iterator& operator++();
00435 
00436         /// postfix increment (avoid if possible for better performance)
00437         const_iterator  operator++ (int);
00438 
00439         bool operator==(const const_iterator& other) const
00440             { return get_raw_node() == other.get_raw_node(); }
00441         bool operator!=(const const_iterator& other) const
00442             { return !(*this == other); }
00443 
00444     private:
00445         impl::nipimpl *pimpl_;
00446 
00447         explicit const_iterator (void *data);
00448         void* get_raw_node() const;
00449         void swap (const_iterator &other);
00450 
00451         friend class document;
00452         friend class node;
00453     };
00454 
00455     /**
00456         Returns the number of childer this nodes has. If you just want to
00457         know how if this node has children or not, you should use
00458         xml::node::empty() instead.
00459 
00460         @return The number of children this node has.
00461      */
00462     size_type size() const;
00463 
00464     /**
00465         Find out if this node has any children. This is the same as
00466         xml::node::size() == 0 except it is much faster.
00467 
00468         @return True if this node DOES NOT have any children.
00469         @return False if this node does have children.
00470      */
00471     bool empty() const;
00472 
00473     /**
00474         Get an iterator that points to the beginning of this node's children.
00475 
00476         @return An iterator that points to the beginning of the children.
00477      */
00478     iterator begin();
00479 
00480     /**
00481         Get a const_iterator that points to the beginning of this node's
00482         children.
00483 
00484         @return A const_iterator that points to the beginning of the children.
00485      */
00486     const_iterator begin() const;
00487 
00488     /**
00489         Get an iterator that points one past the last child for this node.
00490 
00491         @return A "one past the end" iterator.
00492      */
00493     iterator end() { return iterator(); }
00494 
00495     /**
00496         Get a const_iterator that points one past the last child for this
00497         node.
00498 
00499         @return A "one past the end" const_iterator
00500      */
00501     const_iterator end() const { return const_iterator(); }
00502 
00503     /**
00504         Get an iterator that points back at this node.
00505 
00506         @return An iterator that points at this node.
00507      */
00508     iterator self();
00509 
00510     /**
00511         Get a const_iterator that points back at this node.
00512 
00513         @return A const_iterator that points at this node.
00514      */
00515     const_iterator self() const;
00516 
00517     /**
00518         Get an iterator that points at the parent of this node. If this node
00519         does not have a parent, this member function will return an "end"
00520         iterator.
00521 
00522         @return An iterator that points to this nodes parent.
00523         @return If no parent, returns the same iterator that xml::node::end() returns.
00524      */
00525     iterator parent();
00526 
00527     /**
00528         Get a const_iterator that points at the parent of this node. If this
00529         node does not have a parent, this member function will return an
00530         "end" const_iterator.
00531 
00532         @return A const_iterator that points to this nodes parent.
00533         @return If no parent, returns the same const_iterator that xml::node::end() returns.
00534      */
00535     const_iterator parent() const;
00536 
00537     /**
00538         Find the first child node that has the given name. If no such node
00539         can be found, this function will return the same iterator that end()
00540         would return.
00541 
00542         This function is not recursive. That is, it will not search down the
00543         tree for the requested node. Instead, it will only search one level
00544         deep, only checking the children of this node.
00545 
00546         @param name The name of the node you want to find.
00547         @return An iterator that points to the node if found.
00548         @return An end() iterator if the node was not found.
00549 
00550         @see elements(const char*), find(const char*, iterator)
00551      */
00552     iterator find(const char *name);
00553 
00554     /**
00555         Find the first child node that has the given name. If no such node
00556         can be found, this function will return the same const_iterator that
00557         end() would return.
00558 
00559         This function is not recursive. That is, it will not search down the
00560         tree for the requested node. Instead, it will only search one level
00561         deep, only checking the children of this node.
00562 
00563         @param name The name of the node you want to find.
00564         @return A const_iterator that points to the node if found.
00565         @return An end() const_iterator if the node was not found.
00566 
00567         @see elements(const char*) const,
00568              find(const char*, const_iterator) const
00569      */
00570     const_iterator find(const char *name) const;
00571 
00572     /**
00573         Find the first child node, starting with the given iterator, that has
00574         the given name. If no such node can be found, this function will
00575         return the same iterator that end() would return.
00576 
00577         This function should be given an iterator to one of this node's
00578         children. The search will begin with that node and continue with all
00579         its sibliings. This function will not recurse down the tree, it only
00580         searches in one level.
00581 
00582         @param name The name of the node you want to find.
00583         @param start Where to begin the search.
00584         @return An iterator that points to the node if found.
00585         @return An end() iterator if the node was not found.
00586 
00587         @see elements(const char*)
00588      */
00589     iterator find(const char *name, const iterator& start);
00590 
00591     /**
00592         Find the first child node, starting with the given const_iterator,
00593         that has the given name. If no such node can be found, this function
00594         will return the same const_iterator that end() would return.
00595 
00596         This function should be given a const_iterator to one of this node's
00597         children. The search will begin with that node and continue with all
00598         its siblings. This function will not recurse down the tree, it only
00599         searches in one level.
00600 
00601         @param name The name of the node you want to find.
00602         @param start Where to begin the search.
00603         @return A const_iterator that points to the node if found.
00604         @return An end() const_iterator if the node was not found.
00605 
00606         @see elements(const char*) const
00607      */
00608     const_iterator find(const char *name, const const_iterator& start) const;
00609 
00610     /**
00611         Returns view of child nodes of type type_element. If no such node
00612         can be found, returns empty view.
00613 
00614         Example:
00615         @code
00616         xml::nodes_view view(root.elements());
00617         for (xml::nodes_view::iterator i = view.begin(); i != view.end(); ++i)
00618         {
00619           ...
00620         }
00621         @endcode
00622 
00623         @return View with all child elements or empty view if there aren't any.
00624         @since  0.6.0
00625 
00626         @see nodes_view
00627      */
00628     nodes_view elements();
00629 
00630     /**
00631         Returns view of child nodes of type type_element. If no such node
00632         can be found, returns empty view.
00633 
00634         Example:
00635         @code
00636         xml::const_nodes_view view(root.elements());
00637         for (xml::const_nodes_view::const_iterator i = view.begin();
00638              i != view.end();
00639              ++i)
00640         {
00641           ...
00642         }
00643         @endcode
00644 
00645         @return View with all child elements or empty view if there aren't any.
00646         @since  0.6.0
00647 
00648         @see const_nodes_view
00649      */
00650     const_nodes_view elements() const;
00651 
00652     /**
00653         Returns view of child nodes of type type_element with name @a name.
00654         If no such node can be found, returns empty view.
00655 
00656         Example:
00657         @code
00658         xml::nodes_view persons(root.elements("person"));
00659         for (xml::nodes_view::iterator i = view.begin(); i != view.end(); ++i)
00660         {
00661           ...
00662         }
00663         @endcode
00664 
00665         @param  name Name of the elements to return.
00666         @return View that contains only elements @a name.
00667         @since  0.6.0
00668      */
00669     nodes_view elements(const char *name);
00670 
00671     /**
00672         Returns view of child nodes of type type_element with name @a name.
00673         If no such node can be found, returns empty view.
00674 
00675         Example:
00676         @code
00677         xml::const_nodes_view persons(root.elements("person"));
00678         for (xml::const_nodes_view::const_iterator i = view.begin();
00679              i != view.end();
00680              ++i)
00681         {
00682           ...
00683         }
00684         @endcode
00685 
00686         @param  name Name of the elements to return.
00687         @return View that contains only elements @a name.
00688         @since  0.6.0
00689      */
00690     const_nodes_view elements(const char *name) const;
00691 
00692     /**
00693         Insert a new child node. The new node will be inserted at the end of
00694         the child list. This is similar to the xml::node::push_back member
00695         function except that an iterator to the inserted node is returned.
00696 
00697         @param n The node to insert as a child of this node.
00698         @return An iterator that points to the newly inserted node.
00699      */
00700     iterator insert(const node& n);
00701 
00702     /**
00703         Insert a new child node. The new node will be inserted before the
00704         node pointed to by the given iterator.
00705 
00706         @param position An iterator that points to the location where the new node should be inserted (before it).
00707         @param n The node to insert as a child of this node.
00708         @return An iterator that points to the newly inserted node.
00709      */
00710     iterator insert(const iterator& position, const node& n);
00711 
00712     /**
00713         Replace the node pointed to by the given iterator with another node.
00714         The old node will be removed, including all its children, and
00715         replaced with the new node. This will invalidate any iterators that
00716         point to the node to be replaced, or any pointers or references to
00717         that node.
00718 
00719         @param old_node An iterator that points to the node that should be removed.
00720         @param new_node The node to put in old_node's place.
00721         @return An iterator that points to the new node.
00722      */
00723     iterator replace(const iterator& old_node, const node& new_node);
00724 
00725     /**
00726         Erase the node that is pointed to by the given iterator. The node
00727         and all its children will be removed from this node. This will
00728         invalidate any iterators that point to the node to be erased, or any
00729         pointers or references to that node.
00730 
00731         @param to_erase An iterator that points to the node to be erased.
00732         @return An iterator that points to the node after the one being erased.
00733      */
00734     iterator erase(const iterator& to_erase);
00735 
00736     /**
00737         Erase all nodes in the given range, from frist to last. This will
00738         invalidate any iterators that point to the nodes to be erased, or any
00739         pointers or references to those nodes.
00740 
00741         @param first The first node in the range to be removed.
00742         @param last An iterator that points one past the last node to erase. Think xml::node::end().
00743         @return An iterator that points to the node after the last one being erased.
00744      */
00745     iterator erase(iterator first, const iterator& last);
00746 
00747     /**
00748         Erase all children nodes with the given name. This will find all
00749         nodes that have the given node name and remove them from this node.
00750         This will invalidate any iterators that point to the nodes to be
00751         erased, or any pointers or references to those nodes.
00752 
00753         @param name The name of nodes to remove.
00754         @return The number of nodes removed.
00755      */
00756     size_type erase(const char *name);
00757 
00758     /**
00759         Sort all the children nodes of this node using one of thier
00760         attributes. Only nodes that are of xml::node::type_element will be
00761         sorted, and they must have the given node_name.
00762 
00763         The sorting is done by calling std::strcmp on the value of the given
00764         attribute.
00765 
00766         @param node_name The name of the nodes to sort.
00767         @param attr_name The attribute to sort on.
00768      */
00769     void sort(const char *node_name, const char *attr_name);
00770 
00771     /**
00772         Sort all the children nodes of this node using the given comparison
00773         function object. All element type nodes will be considered for
00774         sorting.
00775 
00776         @param compare The binary function object to call in order to sort all child nodes.
00777      */
00778     template <typename T> void sort (T compare)
00779         { impl::sort_callback<T> cb(compare); sort_fo(cb); }
00780 
00781     /**
00782         Convert the node and all its children into XML text and set the given
00783         string to that text.
00784 
00785         @param xml The string to set the node's XML data to.
00786      */
00787     void node_to_string(std::string& xml) const;
00788 
00789     /**
00790         Write a node and all of its children to the given stream.
00791 
00792         @param stream The stream to write the node as XML.
00793         @param n The node to write to the stream.
00794         @return The stream.
00795      */
00796     friend std::ostream& operator<< (std::ostream &stream, const node &n);
00797 
00798 private:
00799     impl::node_impl *pimpl_;
00800 
00801     // private ctor to create uninitialized instance
00802     explicit node(int);
00803 
00804     void set_node_data(void *data);
00805     void* get_node_data();
00806     void* release_node_data();
00807 
00808     void sort_fo(impl::cbfo_node_compare &fo);
00809 
00810     friend class tree_parser;
00811     friend class impl::node_iterator;
00812     friend class document;
00813     friend struct impl::doc_impl;
00814     friend struct impl::node_cmp;
00815 };
00816 
00817 } // namespace xml
00818 
00819 #endif // _xmlwrapp_node_h_