00001 #ifndef DVXML_NODE_H 00002 #define DVXML_NODE_H 00003 // $Id: node.h,v 1.31 2008/01/07 14:45:20 dvermeir Exp $ 00004 #include <stdexcept> 00005 #include <iostream> 00006 #include <iterator> 00007 #include <dvutil/tostring.h> 00008 #include <xmlwrapp/xmlwrapp.h> 00009 #include <dvxml/tohtml.h> 00010 #include <dvxml/exception.h> 00011 #include <dvxml/noconst.h> 00012 #include <dvxml/dv_forward_iterator.h> 00013 00014 namespace Dv { 00015 namespace Xml { 00016 00017 /** Convenience interface to xml::node. 00018 * There are two classes: 00019 * - Dv::Xml::Node which is publicly derived from xml::node. All it 00020 * adds to xml::node are constructors using std::string insteaf of 00021 * const char*. 00022 * - Dv::Xml::Node::Ref which encapsulates a xml::node::iterator 00023 * (there is no version for xml::node::const_iterator). Thus a 00024 * Dv::Xml::Node::Ref object can be thought of as a pointer into 00025 * an XML tree. 00026 * 00027 * The intention is that Dv::Xml::Node is only used for "roots" in 00028 * XML tree structures, as in 00029 * \code 00030 * Dv::Xml::Node node("rootlabel"); 00031 * \endcode 00032 * 00033 * For all other operations, Dv::Xml::Node::Ref should be used. 00034 * A strange feature is that Dv::Xml::Node::Ref::operator* 00035 * returns a reference to itself. The reason is that returning 00036 * a reference to a Dv::Xml::Node would involve copying the 00037 * underlying xml::node. On the other hand, returning a reference 00038 * to the underlying xml::node would imply that the convenient member 00039 * functions of Dv::Xml::Node::Ref would not be available on the 00040 * result of Dv::Xml::Node::Ref::operator* . 00041 * 00042 * For convenience, some Dv::Xml::Node::Ref operations are also 00043 * available on Dv::Xml::Node, either by direct delegation (e.g. 00044 * Dv::Xml::Node::operator[], Dv::Xml::Node::operator()) or 00045 * via a user-defined convertor that converst a Dv::Xml::Node to 00046 * a Dv::Xml::Node::Ref referring to this node. 00047 * 00048 * The main difference with the underlying xmlwrapp interface is that 00049 * many operations are available through expressions. E.g. \a 00050 * (n/"login"/"name")("first_name"), with \a n a Dv::Xml::Node of 00051 * Dv::Xml::Node::Ref object, * refers to the \a first_name attribute of 00052 * the node obtained from \a n by taking the first "login" child and then 00053 * the first "name" child. 00054 * 00055 * Intuitively, for a Dv::Xml::Node::Ref \a n, \a n/"label" returns 00056 * a Dv::Xml::Node::Ref referring to the first child node with \a "label" 00057 * as name. The increment operator returns the next child with the 00058 * same name. E.g. 00059 * \code 00060 * Dv::Xml::Node::Ref n; 00061 * .. 00062 * Dv::Xml::Node::Ref c(n/"label"); 00063 * ++c // refer to 2nd child of n with name "label" 00064 * \endcode 00065 * 00066 * The \a > operator can be used to create new child nodes. 00067 * E.g. \a n>"label" returns a new child of \a n with name \a "label". 00068 * The same operator also works with a Dv::Xml::Node argument. 00069 * \code 00070 * Dv::Xml::Node::Ref n; 00071 * Dv::Xml::Node::Ref c; 00072 * (n >> c) // attach a copy of c as a child to n 00073 * \endcode 00074 * 00075 * Attributes can be set and accessed using \a operator[] and 00076 * \a operator() respectively. 00077 * \code 00078 * Dv::Xml::Node::Ref n; 00079 * n["first_name"] = "blabla"; // set attribute 00080 * if (n("first_name") != "blabla") // obtain attribute value 00081 * throw std::logic_error("BUG"); 00082 * \endcode 00083 * 00084 * The text content of a Dv::Xml::Node::Ref can be obtained by a conversion 00085 * (to std::string) operator. Assigning a std::string to a 00086 * Dv::Xml::Node::Ref has the same effect as xml::node::set_content(). 00087 * 00088 */ 00089 class Node: public xml::node { 00090 public: 00091 class Ref; 00092 00093 /** Auxiliary class for attribute access. 00094 * Dv::Xml::Node::Ref::operator[](const std::string) returns an 00095 * AttributeReference object. 00096 */ 00097 class AttributeReference { 00098 friend class Ref; 00099 public: 00100 /** Set attribute referred to by this reference. 00101 * @warning The value will be automatically converted to 00102 * legal XML text (i.e. '&' will become '&'). 00103 * @param value to assign to attribute. 00104 * @return value 00105 */ 00106 const std::string& operator=(const std::string& value); 00107 00108 /** Set attribute referred to by this reference, after converting 00109 * the parameter object to a std::string. The conversion is done 00110 * using Dv::Util::tostring<T>. 00111 * @param t value to assign, after conversion, to attribute. 00112 * @return value 00113 */ 00114 template <typename T> 00115 const std::string& operator=(const T& t) { 00116 return this->operator=(Dv::Util::tostring<T>(t)); 00117 } 00118 00119 /** Retrieve value of attribute referred to by this reference. 00120 * @return value of attribute referred to by this reference, or 00121 * empty string if there is no attribute value associated with 00122 * this reference. 00123 */ 00124 std::string str() const; 00125 00126 /** Retrieve value of attribute referred to by this reference. 00127 * @return value of attribute referred to by this reference, or 00128 * empty string if there is no attribute value associated with 00129 * this reference. 00130 */ 00131 operator std::string() const { return str(); } 00132 00133 /** Explicit conversion to any type that can be converted by 00134 * Dv::Util::fromstring. 00135 * @param t lvalue referring to object resulting from the conversion 00136 * @return reference to first parameter (t). 00137 */ 00138 template<typename T> 00139 T& conv(T& t) const { 00140 if (! Dv::Util::fromstring(t, str()) ) 00141 throw Exception("Cannot convert AttributeReference to T"); 00142 return t; 00143 } 00144 00145 /** Template user-defined conversion function. 00146 * @warning This will not work for std::string (and others), unless 00147 * the "assignment" syntax is used for explicit initializtion, 00148 * as illustrated by the following example. 00149 * \code 00150 * Dv::Xml::Node::Ref n; 00151 * std::string s1(n["a"]); // error 00152 * std::string s2 = n["a"]; // OK 00153 * \endcode 00154 * The initialization of @a s1 is ambiguous: \a n["a"] may be converted 00155 * to a (single) paramater for a std::string ctor using at least two 00156 * instantiations of the user-defined conversion template below: 00157 * - std::string(const char*) 00158 * - std::string(const std::string&) 00159 */ 00160 template<typename T> 00161 operator T() const { 00162 typename noconst<T>::mutable_type t; 00163 conv(t); 00164 return t; 00165 } 00166 00167 00168 private: 00169 /** Constructor 00170 * @param n reference to xml::node for which the attribute is 00171 * considered 00172 * @param name of the attribute 00173 */ 00174 AttributeReference(const xml::node::iterator n, const std::string& name); 00175 00176 const std::string name; 00177 xml::node::iterator node; 00178 }; 00179 00180 /** A reference to an xml::node object. */ 00181 class Ref: public dv_forward_iterator<Node::Ref> { 00182 friend class Node; 00183 friend class Document; 00184 public: 00185 00186 /** Construct a Dv::Xml::Node::Ref out of a (copy of a) xml::node object. 00187 * @param node xml::node which will be reference by the new Dv::Xml::Node::Ref object. 00188 */ 00189 Ref(xml::node& node); 00190 00191 /** @return name of underlying xml::node 00192 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref 00193 * does not refer to a valid xml::node. 00194 * @sa Dv::Xml::Node::Ref::nil 00195 */ 00196 std::string name() const throw (Dv::Xml::Exception); 00197 00198 /** Set name of underlying xml::node 00199 * @param nm new name of node 00200 * @return *this 00201 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref does not refer 00202 * to a valid xml::node. 00203 * @sa Dv::Xml::Node::Ref::nil 00204 */ 00205 Node::Ref& name(const std::string& nm) throw (Exception); 00206 00207 /** Is this a "non-null" Dv::Xml::Node::Ref, i.e. does it refer to a valid 00208 * xml::node? 00209 * @return true iff this Dv::Xml::Node::Ref does not refer to a valid xml::node. 00210 */ 00211 bool nil() const { return nil_; } 00212 00213 /** Is this not a valid Dv::Xml::Node::Ref, i.e. does it not refer to a valid 00214 * xml::node? 00215 * @return true iff this Dv::Xml::Node::Ref does not refer to a valid xml::node. 00216 * @sa Dv::Xml::Node::Ref::nil 00217 */ 00218 bool operator!() const { return nil(); } 00219 00220 /** Equality test. 00221 * @param m Dv::Xml::Node::Ref to compare this reference with. 00222 * @return true iff both nodes are nil or they refer to the same xml::node. 00223 */ 00224 bool equals(const Node::Ref& m) const; 00225 00226 /** Retrieve underlying xml::node for this Dv::Xml::Node::Ref. 00227 * This function can also be used to check whether this is a nil node. 00228 * \code 00229 * Dv::Xml::Node::Ref n(root/"child"/"grandchild"); 00230 * if (n) { 00231 * .. 00232 * } 00233 * \endcode 00234 * @return pointer to xml::node to which this Dv::Xml::Node::Ref 00235 * refers, or 0 if it is a "nil" node. 00236 * @sa Dv::Xml::Node::Ref::nil 00237 */ 00238 operator const xml::node*() const; 00239 operator xml::node*(); 00240 00241 /** Retrieve child node (of this node) with matching name 00242 * @param name to match in returned child node 00243 * @return Dv::Xml::Node::Ref referring to first child of this node that 00244 * has name or nil. 00245 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref does not refer to a valid 00246 * xml::node. 00247 * @sa Dv::Xml::Node::Ref::nil 00248 */ 00249 Node::Ref find(const std::string& name) const throw (Exception); 00250 00251 /** Return Ref that points past the last child of this node. 00252 * @return nil Dv::Xml::Node::Ref. 00253 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref does not refer to a valid 00254 * xml::node. 00255 */ 00256 Ref end() const throw (Exception); 00257 00258 /** Return next child of parent with same name 00259 * @return Dv::Xml::Node::Ref referring to next sibling of this node that 00260 * has the same name. 00261 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref 00262 * does not refer to a valid xml::node. 00263 */ 00264 Ref operator++() throw (Exception); 00265 00266 /** Dummy dereference operator, const version. 00267 * This member function is needed to support forward iterator interface. 00268 * @return reference to self. 00269 */ 00270 const Node::Ref& operator*() const { return *this; } 00271 00272 /** Dummy dereference operator, non-const version. 00273 * This member function is needed to support forward iterator interface. 00274 * @return reference to self. 00275 */ 00276 Node::Ref& operator*() { return *this; } 00277 00278 /** Append a new text node to the list of children of this node. 00279 * @param name of the new node 00280 * @param contents of the new node 00281 * @return Dv::Xml::Node::Ref referring to the new child of this node. 00282 * @exception Dv::Xml::Exception if the target does not refer to a 00283 * valid xml::node. 00284 */ 00285 Node::Ref add(const std::string& name, const std::string& contents) 00286 throw (Dv::Xml::Exception); 00287 00288 /** Append a new node to the list of children of this node. 00289 * @param name of the new node 00290 * @return Dv::Xml::Node::Ref referring to the new child of this node. 00291 * @exception Dv::Xml::Exception if the target does not refer to a 00292 * valid xml::node. 00293 */ 00294 Node::Ref add(const char* name) throw (Exception); 00295 00296 /** Append a new node to the list of children of this node. 00297 * @param name of the new node 00298 * @return Dv::Xml::Node::Ref referring to the new child of this node. 00299 * @exception Dv::Xml::Exception if the target does not refer to a 00300 * valid xml::node. 00301 */ 00302 Node::Ref add(const std::string& name) throw (Exception) { 00303 return add(name.c_str()); 00304 } 00305 00306 /** Append copy of node to children of this node. 00307 * @param child a copy of which will be added to the children of this node. 00308 * @return Dv::Xml::Node::Ref referring to the new child of this node. 00309 * @exception Dv::Xml::Exception if either of the parameters does not refer to a 00310 * valid xml::node. 00311 */ 00312 Node::Ref add(const Node::Ref& child) throw (Exception); 00313 00314 /** Check whether this node has an attribute value for given key. 00315 * @param name key of attribute 00316 * @return true iff this node has an attribute value of this key. 00317 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref does not refer 00318 * to a valid xml::node. 00319 */ 00320 bool defined(const std::string& name) const throw (Exception); 00321 00322 /** Retrieve attribute value. 00323 * @param name key of attribute 00324 * @return value of attribute 00325 * @exception Dv::Xml::Exception if this node has no attribute for key 00326 * "name" or this node does not refer to a valid xml::node. 00327 */ 00328 const std::string operator()(const std::string& name) const throw (Exception); 00329 00330 /** Set attribute value. 00331 * @param name key of attribute 00332 * @return AttributeReference that can be used to either retrieve 00333 * the current value of assign a new one. If there is no 00334 * attribute value, the empty string will be returned (and 00335 * stored). 00336 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref does not refer 00337 * to a valid xml::node. 00338 * @sa Dv::Xml::Node::AttributeReference 00339 * \code 00340 * Dv::Xml::Node::Ref n; 00341 * .. 00342 * n["name"] = "fred"; 00343 * std::cout << n["name"] << std::endl; 00344 * \endcode 00345 */ 00346 AttributeReference operator[](const std::string& name) throw (Exception); 00347 00348 /** Retrieve text content. 00349 * Note that the resulting string is trimmed, i.e. leading and 00350 * trailing white space is removed. To prevent trimming: use 00351 * Dv::Xml::Node::Ref::str(false). 00352 * @return text content of text-xml::node children of this 00353 * Dv::Xml::Node::Ref. 00354 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref does not refer 00355 * to a valid xml::node. 00356 * @sa Dv::Xml::Node::Ref::str 00357 */ 00358 operator std::string() const throw (Exception); 00359 00360 /** Template user-defined conversion function. 00361 * @warning This will not work for std::string (and others), unless 00362 * the "assignment" syntax is used for explicit initializtion, 00363 * as illustrated by the following example. 00364 * \code 00365 * Dv::Xml::Node::Ref n; 00366 * std::string s1(n["a"]); // error 00367 * std::string s2 = n["a"]; // OK 00368 * \endcode 00369 * The initialization of @a s1 is ambiguous: \a n["a"] may be converted 00370 * to a (single) paramater for a std::string ctor using at least two 00371 * instantiations of the user-defined conversion template below: 00372 * - std::string(const char*) 00373 * - std::string(const std::string&) 00374 */ 00375 template<typename T> 00376 operator T() const { 00377 typename noconst<T>::mutable_type t; 00378 Dv::Util::fromstring(t, str()); 00379 return t; 00380 } 00381 00382 /** Retrieve text content. 00383 * @return text content of text-xml::node children of this 00384 * Dv::Xml::Node::Ref. 00385 * @param trim if true, remove leading and trailing white space from result. 00386 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref does not refer 00387 * to a valid xml::node. 00388 */ 00389 std::string str(bool trim=true) const throw (Exception); 00390 00391 /** Set text content. 00392 * @param text to be used as content for this node. 00393 * @warning Note that the text parameter must be legal XML (see test-node-5 in 00394 * the distrbution). 00395 * @return reference to this node. All children of this node will 00396 * have been zapped and a new single child xml::node of type text 00397 * will have been inserted. 00398 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref does not 00399 * refer to a valid xml::node. 00400 * @see Dv::Xml::to_html 00401 */ 00402 Ref& operator=(const std::string& text) throw (Exception); 00403 00404 /** Set content of node referred to by this reference, after converting 00405 * the parameter object to a std::string. The conversion is done 00406 * using Dv::Util::tostring<T>. 00407 * @param t value to assign, after conversion, to attribute. 00408 * @return string representation of @a t. 00409 */ 00410 template <typename T> 00411 const std::string operator=(const T& t) { 00412 return this->operator=(Dv::Util::tostring<T>(t)); 00413 } 00414 00415 /** Replace this node by another one. The replacement will 00416 * take place in the tree of which this Ref is a part. 00417 * @param ref reference to xml::node of which a copy will replace this node. 00418 * @return reference to this Dv::Xml::Node::Ref. 00419 * @warning the xml::node to which ref refers will be copied. 00420 */ 00421 Ref& replace(const Ref& ref); 00422 00423 protected: 00424 /** Constructor. 00425 * @param it iterator, possibly referring to xml::node 00426 * @param nil true iff it does not refer to a valid xml::node. 00427 */ 00428 explicit Ref(xml::node::iterator it, bool nil=false); 00429 /** Constructor. 00430 * @param it const_iterator, possibly referring to xml::node 00431 * @param nil true iff it does not refer to a valid xml::node. 00432 */ 00433 explicit Ref(xml::node::const_iterator it, bool nil=false); 00434 /** Throw an exception if this Dv::Xml::Node::Ref object does 00435 * not refer to a valid xml::node. 00436 * @param message to be used in the generated exception. 00437 */ 00438 void assert_valid(const std::string& message) const throw (Dv::Xml::Exception); 00439 00440 private: 00441 /** Refers to xml::node, if valid. */ 00442 xml::node::iterator it_; 00443 /** False iff it_ refers to a valid xml::node. */ 00444 bool nil_; 00445 }; 00446 00447 /** Default constructor. */ 00448 Node(): xml::node() {} 00449 00450 /** Create an xml::node with a given name. 00451 * @param name of new xml::node. 00452 */ 00453 explicit Node(const std::string& name): xml::node(name.c_str()) {} 00454 00455 00456 /** Create an xml::node with a given name and content. 00457 * @param name of new xml::node. 00458 * @param content text content of new xml::node. 00459 */ 00460 Node(const std::string& name, const std::string& content): 00461 // xml::node(name.c_str(), to_html(content).c_str()) {} 00462 xml::node(name.c_str(), content.c_str()) {} 00463 00464 template<typename T> 00465 explicit Node(const std::string& name, const T& c): 00466 xml::node(name.c_str(), Dv::Util::tostring(c).c_str()) {} 00467 00468 /** Return a Dv::Xml::Node::Ref object referring to this Node. */ 00469 Ref ref() const { 00470 return Ref(const_cast<xml::node*>(static_cast<const xml::node*>(this))->self()); 00471 } 00472 00473 /** Return a Dv::Xml::Node::Ref object referring to this Node. */ 00474 Ref ref() { 00475 return Ref(const_cast<xml::node*>(static_cast<xml::node*>(this))->self()); 00476 } 00477 00478 /** Return a Dv::Xml::Node::Ref object referring to this Node. */ 00479 operator Node::Ref() { return ref(); } 00480 00481 /** Return a Dv::Xml::Node::Ref object referring to this Node. */ 00482 operator Node::Ref() const { return ref(); } 00483 00484 /** Set attribute value. 00485 * @param name key of attribute 00486 * @return Dv::Xml::Node::AttributeReference that can be used to either retrieve 00487 * the current value of assign a new one. If there 00488 * @sa Dv::Xml::Node::AttributeReference 00489 * \code 00490 * Dv::Xml::Node::Ref n; 00491 * .. 00492 * n["name"] = "fred"; 00493 * std::cout << n["name"] << std::endl; 00494 * \endcode 00495 */ 00496 AttributeReference operator[](const std::string& name) { return ref()[name]; } 00497 00498 /** Retrieve attribute value. 00499 * @param name key of attribute 00500 * @return value of attribute 00501 * @exception Dv::Xml::Exception if this node has no attribute for key "name". 00502 */ 00503 const std::string operator()(const std::string& name) const throw (Exception) { 00504 return ref()(name); 00505 } 00506 00507 /** Return Ref that points past the last child of this node. 00508 * @return nil Dv::Xml::Node::Ref. 00509 */ 00510 const Ref end() const { return ref().end(); } 00511 00512 /** @return name of underlying xml::node */ 00513 std::string name() const { return get_name(); } 00514 00515 /** Add another node as a child to this node. 00516 * @param ref reference to node to add 00517 * @return *this 00518 */ 00519 Node& add(const Node::Ref& ref); 00520 00521 00522 /** Add another node as a child to this node. 00523 * @param ref to Node to add 00524 * @return *this 00525 Node& add(const Node::Ref& ref) { 00526 *this >> ref; 00527 return *this; 00528 } 00529 */ 00530 00531 /** Add a new node as a child to this node. 00532 * @param name of new node to add as a child 00533 * @return *this 00534 */ 00535 Node& add(const std::string& name) { 00536 add(Node(name)); 00537 return *this; 00538 } 00539 00540 /** Add a new text node as a child to this node. 00541 * @param name of the new node to add as a child 00542 * @param contents of the new node to add as a child 00543 * @return *this 00544 */ 00545 Node& add(const std::string& name, const std::string& contents) { 00546 add(Node(name, contents)); 00547 return *this; 00548 } 00549 00550 /** Add a new text node as a child to this node. 00551 * @param name of the new node to add as a child 00552 * @param contents of the new node to add as a child 00553 * @return *this 00554 */ 00555 template<typename T> 00556 Node& add(const std::string& name, const T& contents) { 00557 add(Node(name, Dv::Util::tostring(contents))); 00558 return *this; 00559 } 00560 }; 00561 00562 /** Print an XML tree rooted at the node referred to by a 00563 * Dv::Xml::Node::Ref object. 00564 * @param os stream to print to 00565 * @param ref reference to xml::node (may be invalid) 00566 * @warning The function will print "nil" if the object does 00567 * not refer to a valid xml::node. 00568 */ 00569 std::ostream& 00570 operator<<(std::ostream& os, const Node::Ref& ref); 00571 00572 /** Retrieve child node with matching name 00573 * @param ref reference to xml::node of which child is to be found 00574 * @param name to match in returned child node 00575 * @return Dv::Xml::Node::Ref referring to first child of this node that 00576 * has name or nil. 00577 * @exception Dv::Xml::Exception if this Dv::Xml::Node::Ref does not refer to a valid 00578 * xml::node. 00579 * @sa Dv::Xml::Node::Ref::nil 00580 */ 00581 inline Node::Ref operator/(const Node::Ref& ref, const std::string& name) throw (Exception) { 00582 return ref.find(name); 00583 } 00584 00585 /** Equality test. 00586 * @param n Dv::Xml::Node::Ref to compare with. 00587 * @param m Dv::Xml::Node::Ref to compare with. 00588 * @return true iff both nodes are nil or they refer to the same xml::node. 00589 */ 00590 inline bool operator==(const Node::Ref& n, const Node::Ref& m) { 00591 return n.equals(m); 00592 } 00593 00594 /** Inequality test. 00595 * @param m Dv::Xml::Node::Ref to compare with. 00596 * @param n Dv::Xml::Node::Ref to compare with. 00597 * @return true iff the nodes are not equal 00598 * @sa Dv::Xml::operator==(const Node::Ref& n, const Node::Ref& m) 00599 */ 00600 inline bool operator!=(const Node::Ref m, const Node::Ref& n) { 00601 return ! (m.equals(n)); 00602 } 00603 00604 /** Append new child node with given name. 00605 * @param ref to node to which a new child node will be appended. 00606 * @param name for new child node. 00607 * @return Dv::Xml::Node::Ref referring to new child of this node that 00608 * has name. 00609 * @exception Dv::Xml::Exception if \a ref does not refer to 00610 * a valid xml::node. 00611 */ 00612 inline Node::Ref operator>>(Node::Ref ref, const std::string& name) throw (Exception) { 00613 return ref.add(name); 00614 } 00615 00616 /** Append new child node with given name. 00617 * @param ref to node to which a new child node will be appended. 00618 * @param name for new child node. 00619 * @return Dv::Xml::Node::Ref referring to new child of this node that 00620 * has name. 00621 * @exception Dv::Xml::Exception if \a ref does not refer to 00622 * a valid xml::node. 00623 */ 00624 inline Node::Ref operator>>(Node::Ref ref, const char* name) throw (Exception) { 00625 return ref.add(name); 00626 } 00627 00628 /** Append copy of node to children of this node. 00629 * @param ref reference to xml::node to which a child will be added. 00630 * @param child a copy of which will be added to the children of this node. 00631 * @return Dv::Xml::Node::Ref referring to the new child of this node. 00632 * @exception Dv::Xml::Exception if either of the parameters does not refer to a 00633 * valid xml::node. 00634 */ 00635 inline Node::Ref operator>>(Node::Ref ref, Node::Ref child) throw (Exception) { 00636 return ref.add(child); 00637 } 00638 00639 inline std::ostream& operator<<(std::ostream& os, const Node::AttributeReference& a) { 00640 return os << a.str(); 00641 } 00642 } 00643 } 00644 00645 #endif
dvxml-0.1.7 | [ 7 January, 2008] |