00001 /* 00002 * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org) 00003 * 2009 Vaclav Slavik <vslavik@fastmail.fm> 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; 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 @author Peter Jones 00170 */ 00171 node(); 00172 00173 /** 00174 Construct a new xml::node and set the name of the node. 00175 00176 @param name The name of the new node. 00177 @author Peter Jones 00178 */ 00179 explicit node(const char *name); 00180 00181 /** 00182 Construct a new xml::node given a name and content. The content will 00183 be used to create a new child text node. 00184 00185 @param name The name of the new element. 00186 @param content The text that will be used to create a child node. 00187 @author Peter Jones 00188 */ 00189 node(const char *name, const char *content); 00190 00191 /** 00192 Construct a new xml::node that is of type_cdata. The cdata_info 00193 parameter should contain the contents of the CDATA section. 00194 00195 @note Sample Use Example: 00196 @code 00197 xml::node mynode(xml::node::cdata("This is a CDATA section")); 00198 @endcode 00199 00200 @param cdata_info A cdata struct that tells xml::node what the 00201 content will be. 00202 @author Peter Jones 00203 */ 00204 explicit node(cdata cdata_info); 00205 00206 /** 00207 Construct a new xml::node that is of type_comment. The comment_info 00208 parameter should contain the contents of the XML comment. 00209 00210 @note Sample Use Example: 00211 @code 00212 xml::node mynode(xml::node::comment("This is an XML comment")); 00213 @endcode 00214 00215 @param comment_info A comment struct that tells xml::node what the comment will be. 00216 @author Peter Jones 00217 */ 00218 explicit node(comment comment_info); 00219 00220 /** 00221 Construct a new xml::node that is of type_pi. The pi_info parameter 00222 should contain the name of the XML processing instruction (PI), and 00223 optionally, the contents of the XML PI. 00224 00225 @note Sample Use Example: 00226 @code 00227 xml::node mynode(xml::node::pi("xslt", "stylesheet=\"test.xsl\"")); 00228 @endcode 00229 00230 @param pi_info A pi struct that tells xml::node what the name and contents of the XML PI are. 00231 @author Peter Jones 00232 */ 00233 explicit node(pi pi_info); 00234 00235 /** 00236 Construct a new xml::node that is of type_text. The text_info 00237 parameter should contain the text. 00238 00239 @note Sample Use Example: 00240 @code 00241 xml::node mynode(xml::node::text("This is XML text")); 00242 @endcode 00243 00244 @param text_info A text struct that tells xml::node what the text will be. 00245 @author Vaclav Slavik 00246 */ 00247 explicit node(text text_info); 00248 00249 /** 00250 Construct a new xml::node by copying another xml::node. 00251 00252 @param other The other node to copy. 00253 @author Peter Jones 00254 */ 00255 node(const node& other); 00256 00257 /** 00258 Make this node equal to some other node via assignment. 00259 00260 @param other The other node to copy. 00261 @return A reference to this node. 00262 @author Peter Jones 00263 */ 00264 node& operator=(const node& other); 00265 00266 /** 00267 Class destructor 00268 00269 @author Peter Jones 00270 */ 00271 ~node(); 00272 00273 /** 00274 Set the name of this xml::node. 00275 00276 @param name The new name for this xml::node. 00277 @author Peter Jones 00278 */ 00279 void set_name(const char *name); 00280 00281 /** 00282 Get the name of this xml::node. 00283 00284 This function may change in the future to return std::string. 00285 Feedback is welcome. 00286 00287 @return The name of this node. 00288 @author Peter Jones 00289 */ 00290 const char* get_name() const; 00291 00292 /** 00293 Set the content of a node. If this node is an element node, this 00294 function will remove all of its children nodes and replace them 00295 with one text node set to the given string. 00296 00297 @param content The content of the text node. 00298 @author Peter Jones 00299 */ 00300 void set_content(const char *content); 00301 00302 /** 00303 Get the content for this text node. If this node is not a text node 00304 but it has children nodes that are text nodes, the contents of those 00305 child nodes will be returned. If there is no content or these 00306 conditions do not apply, zero will be returned. 00307 00308 This function may change in the future to return std::string. 00309 Feedback is welcome. 00310 00311 @return The content or 0. 00312 @author Peter Jones 00313 */ 00314 const char* get_content() const; 00315 00316 /** 00317 Get this node's "type". You can use that information to know what you 00318 can and cannot do with it. 00319 00320 @return The node's type. 00321 @author Peter Jones 00322 */ 00323 node_type get_type() const; 00324 00325 /** 00326 Get the list of attributes. You can use the returned object to get 00327 and set the attributes for this node. Make sure you use a reference 00328 to this returned object, to prevent a copy. 00329 00330 @return The xml::attributes object for this node. 00331 @author Peter Jones 00332 */ 00333 xml::attributes& get_attributes(); 00334 00335 /** 00336 Get the list of attributes. You can use the returned object to get 00337 the attributes for this node. Make sure you use a reference to this 00338 returned object, to prevent a copy. 00339 00340 @return The xml::attributes object for this node. 00341 @author Peter Jones 00342 */ 00343 const xml::attributes& get_attributes() const; 00344 00345 /** 00346 Get the namespace of this xml::node. 00347 00348 @return The namespace of this node or NULL if no namespace is 00349 associated. 00350 @author Vaclav Slavik 00351 @since 0.6.0 00352 */ 00353 const char* get_namespace() const; 00354 00355 /** 00356 Find out if this node is a text node or sometiming like a text node, 00357 CDATA for example. 00358 00359 @return True if this node is a text node; false otherwise. 00360 @author Peter Jones 00361 */ 00362 bool is_text() const; 00363 00364 /** 00365 Add a child xml::node to this node. 00366 00367 @param child The child xml::node to add. 00368 @author Peter Jones 00369 */ 00370 void push_back(const node& child); 00371 00372 /** 00373 Swap this node with another one. 00374 00375 @param other The other node to swap with. 00376 @author Peter Jones 00377 */ 00378 void swap(node& other); 00379 00380 class const_iterator; // forward declaration 00381 00382 /** 00383 The xml::node::iterator provides a way to access children nodes 00384 similar to a standard C++ container. The nodes that are pointed to by 00385 the iterator can be changed. 00386 */ 00387 class iterator 00388 { 00389 public: 00390 typedef node value_type; 00391 typedef int difference_type; 00392 typedef value_type* pointer; 00393 typedef value_type& reference; 00394 typedef std::forward_iterator_tag iterator_category; 00395 00396 iterator() : pimpl_(0) {} 00397 iterator(const iterator& other); 00398 iterator& operator=(const iterator& other); 00399 ~iterator(); 00400 00401 reference operator* () const; 00402 pointer operator->() const; 00403 00404 /// prefix increment 00405 iterator& operator++(); 00406 00407 /// postfix increment (avoid if possible for better performance) 00408 iterator operator++ (int); 00409 00410 bool operator==(const iterator& other) const 00411 { return get_raw_node() == other.get_raw_node(); } 00412 bool operator!=(const iterator& other) const 00413 { return !(*this == other); } 00414 00415 private: 00416 impl::nipimpl *pimpl_; 00417 00418 explicit iterator (void *data); 00419 void* get_raw_node() const; 00420 void swap (iterator &other); 00421 00422 friend class node; 00423 friend class document; 00424 friend class const_iterator; 00425 }; 00426 00427 /** 00428 The xml::node::const_iterator provides a way to access children nodes 00429 similar to a standard C++ container. The nodes that are pointed to by 00430 the const_iterator cannot be changed. 00431 */ 00432 class const_iterator 00433 { 00434 public: 00435 typedef const node value_type; 00436 typedef int difference_type; 00437 typedef value_type* pointer; 00438 typedef value_type& reference; 00439 typedef std::forward_iterator_tag iterator_category; 00440 00441 const_iterator() : pimpl_(0) {} 00442 const_iterator(const const_iterator &other); 00443 const_iterator(const iterator &other); 00444 const_iterator& operator=(const const_iterator& other); 00445 ~const_iterator(); 00446 00447 reference operator* () const; 00448 pointer operator->() const; 00449 00450 /// prefix increment 00451 const_iterator& operator++(); 00452 00453 /// postfix increment (avoid if possible for better performance) 00454 const_iterator operator++ (int); 00455 00456 bool operator==(const const_iterator& other) const 00457 { return get_raw_node() == other.get_raw_node(); } 00458 bool operator!=(const const_iterator& other) const 00459 { return !(*this == other); } 00460 00461 private: 00462 impl::nipimpl *pimpl_; 00463 00464 explicit const_iterator (void *data); 00465 void* get_raw_node() const; 00466 void swap (const_iterator &other); 00467 00468 friend class document; 00469 friend class node; 00470 }; 00471 00472 /** 00473 Returns the number of childer this nodes has. If you just want to 00474 know how if this node has children or not, you should use 00475 xml::node::empty() instead. 00476 00477 @return The number of children this node has. 00478 @author Peter Jones 00479 */ 00480 size_type size() const; 00481 00482 /** 00483 Find out if this node has any children. This is the same as 00484 xml::node::size() == 0 except it is much faster. 00485 00486 @return True if this node DOES NOT have any children. 00487 @return False if this node does have children. 00488 @author Peter Jones 00489 */ 00490 bool empty() const; 00491 00492 /** 00493 Get an iterator that points to the beginning of this node's children. 00494 00495 @return An iterator that points to the beginning of the children. 00496 @author Peter Jones 00497 */ 00498 iterator begin(); 00499 00500 /** 00501 Get a const_iterator that points to the beginning of this node's 00502 children. 00503 00504 @return A const_iterator that points to the beginning of the children. 00505 @author Peter Jones 00506 */ 00507 const_iterator begin() const; 00508 00509 /** 00510 Get an iterator that points one past the last child for this node. 00511 00512 @return A "one past the end" iterator. 00513 @author Peter Jones 00514 */ 00515 iterator end() { return iterator(); } 00516 00517 /** 00518 Get a const_iterator that points one past the last child for this 00519 node. 00520 00521 @return A "one past the end" const_iterator 00522 @author Peter Jones 00523 */ 00524 const_iterator end() const { return const_iterator(); } 00525 00526 /** 00527 Get an iterator that points back at this node. 00528 00529 @return An iterator that points at this node. 00530 @author Peter Jones 00531 */ 00532 iterator self(); 00533 00534 /** 00535 Get a const_iterator that points back at this node. 00536 00537 @return A const_iterator that points at this node. 00538 @author Peter Jones 00539 */ 00540 const_iterator self() const; 00541 00542 /** 00543 Get an iterator that points at the parent of this node. If this node 00544 does not have a parent, this member function will return an "end" 00545 iterator. 00546 00547 @return An iterator that points to this nodes parent. 00548 @return If no parent, returns the same iterator that xml::node::end() returns. 00549 @author Peter Jones 00550 */ 00551 iterator parent(); 00552 00553 /** 00554 Get a const_iterator that points at the parent of this node. If this 00555 node does not have a parent, this member function will return an 00556 "end" const_iterator. 00557 00558 @return A const_iterator that points to this nodes parent. 00559 @return If no parent, returns the same const_iterator that xml::node::end() returns. 00560 @author Peter Jones 00561 */ 00562 const_iterator parent() const; 00563 00564 /** 00565 Find the first child node that has the given name. If no such node 00566 can be found, this function will return the same iterator that end() 00567 would return. 00568 00569 This function is not recursive. That is, it will not search down the 00570 tree for the requested node. Instead, it will only search one level 00571 deep, only checking the children of this node. 00572 00573 @param name The name of the node you want to find. 00574 @return An iterator that points to the node if found. 00575 @return An end() iterator if the node was not found. 00576 @author Peter Jones 00577 00578 @see elements(const char*), find(const char*, iterator) 00579 */ 00580 iterator find(const char *name); 00581 00582 /** 00583 Find the first child node that has the given name. If no such node 00584 can be found, this function will return the same const_iterator that 00585 end() would return. 00586 00587 This function is not recursive. That is, it will not search down the 00588 tree for the requested node. Instead, it will only search one level 00589 deep, only checking the children of this node. 00590 00591 @param name The name of the node you want to find. 00592 @return A const_iterator that points to the node if found. 00593 @return An end() const_iterator if the node was not found. 00594 @author Peter Jones 00595 00596 @see elements(const char*) const, 00597 find(const char*, const_iterator) const 00598 */ 00599 const_iterator find(const char *name) const; 00600 00601 /** 00602 Find the first child node, starting with the given iterator, that has 00603 the given name. If no such node can be found, this function will 00604 return the same iterator that end() would return. 00605 00606 This function should be given an iterator to one of this node's 00607 children. The search will begin with that node and continue with all 00608 its sibliings. This function will not recurse down the tree, it only 00609 searches in one level. 00610 00611 @param name The name of the node you want to find. 00612 @param start Where to begin the search. 00613 @return An iterator that points to the node if found. 00614 @return An end() iterator if the node was not found. 00615 @author Peter Jones 00616 00617 @see elements(const char*) 00618 */ 00619 iterator find(const char *name, const iterator& start); 00620 00621 /** 00622 Find the first child node, starting with the given const_iterator, 00623 that has the given name. If no such node can be found, this function 00624 will return the same const_iterator that end() would return. 00625 00626 This function should be given a const_iterator to one of this node's 00627 children. The search will begin with that node and continue with all 00628 its siblings. This function will not recurse down the tree, it only 00629 searches in one level. 00630 00631 @param name The name of the node you want to find. 00632 @param start Where to begin the search. 00633 @return A const_iterator that points to the node if found. 00634 @return An end() const_iterator if the node was not found. 00635 @author Peter Jones 00636 00637 @see elements(const char*) const 00638 */ 00639 const_iterator find(const char *name, const const_iterator& start) const; 00640 00641 /** 00642 Returns view of child nodes of type type_element. If no such node 00643 can be found, returns empty view. 00644 00645 Example: 00646 @code 00647 xml::nodes_view view(root.elements()); 00648 for (xml::nodes_view::iterator i = view.begin(); i != view.end(); ++i) 00649 { 00650 ... 00651 } 00652 @endcode 00653 00654 @return View with all child elements or empty view if there aren't any. 00655 @author Vaclav Slavik 00656 @since 0.6.0 00657 00658 @see nodes_view 00659 */ 00660 nodes_view elements(); 00661 00662 /** 00663 Returns view of child nodes of type type_element. If no such node 00664 can be found, returns empty view. 00665 00666 Example: 00667 @code 00668 xml::const_nodes_view view(root.elements()); 00669 for (xml::const_nodes_view::const_iterator i = view.begin(); 00670 i != view.end(); 00671 ++i) 00672 { 00673 ... 00674 } 00675 @endcode 00676 00677 @return View with all child elements or empty view if there aren't any. 00678 @author Vaclav Slavik 00679 @since 0.6.0 00680 00681 @see const_nodes_view 00682 */ 00683 const_nodes_view elements() const; 00684 00685 /** 00686 Returns view of child nodes of type type_element with name @a name. 00687 If no such node can be found, returns empty view. 00688 00689 Example: 00690 @code 00691 xml::nodes_view persons(root.elements("person")); 00692 for (xml::nodes_view::iterator i = view.begin(); i != view.end(); ++i) 00693 { 00694 ... 00695 } 00696 @endcode 00697 00698 @param name Name of the elements to return. 00699 @return View that contains only elements @a name. 00700 @author Vaclav Slavik 00701 @since 0.6.0 00702 */ 00703 nodes_view elements(const char *name); 00704 00705 /** 00706 Returns view of child nodes of type type_element with name @a name. 00707 If no such node can be found, returns empty view. 00708 00709 Example: 00710 @code 00711 xml::const_nodes_view persons(root.elements("person")); 00712 for (xml::const_nodes_view::const_iterator i = view.begin(); 00713 i != view.end(); 00714 ++i) 00715 { 00716 ... 00717 } 00718 @endcode 00719 00720 @param name Name of the elements to return. 00721 @return View that contains only elements @a name. 00722 @author Vaclav Slavik 00723 @since 0.6.0 00724 */ 00725 const_nodes_view elements(const char *name) const; 00726 00727 /** 00728 Insert a new child node. The new node will be inserted at the end of 00729 the child list. This is similar to the xml::node::push_back member 00730 function except that an iterator to the inserted node is returned. 00731 00732 @param n The node to insert as a child of this node. 00733 @return An iterator that points to the newly inserted node. 00734 @author Peter Jones 00735 */ 00736 iterator insert(const node& n); 00737 00738 /** 00739 Insert a new child node. The new node will be inserted before the 00740 node pointed to by the given iterator. 00741 00742 @param position An iterator that points to the location where the new node should be inserted (before it). 00743 @param n The node to insert as a child of this node. 00744 @return An iterator that points to the newly inserted node. 00745 @author Peter Jones 00746 */ 00747 iterator insert(const iterator& position, const node& n); 00748 00749 /** 00750 Replace the node pointed to by the given iterator with another node. 00751 The old node will be removed, including all its children, and 00752 replaced with the new node. This will invalidate any iterators that 00753 point to the node to be replaced, or any pointers or references to 00754 that node. 00755 00756 @param old_node An iterator that points to the node that should be removed. 00757 @param new_node The node to put in old_node's place. 00758 @return An iterator that points to the new node. 00759 @author Peter Jones 00760 */ 00761 iterator replace(const iterator& old_node, const node& new_node); 00762 00763 /** 00764 Erase the node that is pointed to by the given iterator. The node 00765 and all its children will be removed from this node. This will 00766 invalidate any iterators that point to the node to be erased, or any 00767 pointers or references to that node. 00768 00769 @param to_erase An iterator that points to the node to be erased. 00770 @return An iterator that points to the node after the one being erased. 00771 @author Peter Jones 00772 @author Gary A. Passero 00773 */ 00774 iterator erase(const iterator& to_erase); 00775 00776 /** 00777 Erase all nodes in the given range, from frist to last. This will 00778 invalidate any iterators that point to the nodes to be erased, or any 00779 pointers or references to those nodes. 00780 00781 @param first The first node in the range to be removed. 00782 @param last An iterator that points one past the last node to erase. Think xml::node::end(). 00783 @return An iterator that points to the node after the last one being erased. 00784 @author Peter Jones 00785 */ 00786 iterator erase(iterator first, const iterator& last); 00787 00788 /** 00789 Erase all children nodes with the given name. This will find all 00790 nodes that have the given node name and remove them from this node. 00791 This will invalidate any iterators that point to the nodes to be 00792 erased, or any pointers or references to those nodes. 00793 00794 @param name The name of nodes to remove. 00795 @return The number of nodes removed. 00796 @author Peter Jones 00797 */ 00798 size_type erase(const char *name); 00799 00800 /** 00801 Sort all the children nodes of this node using one of thier 00802 attributes. Only nodes that are of xml::node::type_element will be 00803 sorted, and they must have the given node_name. 00804 00805 The sorting is done by calling std::strcmp on the value of the given 00806 attribute. 00807 00808 @param node_name The name of the nodes to sort. 00809 @param attr_name The attribute to sort on. 00810 @author Peter Jones 00811 */ 00812 void sort(const char *node_name, const char *attr_name); 00813 00814 /** 00815 Sort all the children nodes of this node using the given comparison 00816 function object. All element type nodes will be considered for 00817 sorting. 00818 00819 @param compare The binary function object to call in order to sort all child nodes. 00820 @author Peter Jones 00821 */ 00822 template <typename T> void sort (T compare) 00823 { impl::sort_callback<T> cb(compare); sort_fo(cb); } 00824 00825 /** 00826 Convert the node and all its children into XML text and set the given 00827 string to that text. 00828 00829 @param xml The string to set the node's XML data to. 00830 @author Peter Jones 00831 */ 00832 void node_to_string(std::string& xml) const; 00833 00834 /** 00835 Write a node and all of its children to the given stream. 00836 00837 @param stream The stream to write the node as XML. 00838 @param n The node to write to the stream. 00839 @return The stream. 00840 @author Peter Jones 00841 */ 00842 friend std::ostream& operator<< (std::ostream &stream, const node &n); 00843 00844 private: 00845 impl::node_impl *pimpl_; 00846 00847 // private ctor to create uninitialized instance 00848 explicit node(int); 00849 00850 void set_node_data(void *data); 00851 void* get_node_data(); 00852 void* release_node_data(); 00853 00854 void sort_fo(impl::cbfo_node_compare &fo); 00855 00856 friend class tree_parser; 00857 friend class impl::node_iterator; 00858 friend class document; 00859 friend struct impl::doc_impl; 00860 friend struct impl::node_cmp; 00861 }; 00862 00863 } // namespace xml 00864 00865 #endif // _xmlwrapp_node_h_