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