node.h

Go to the documentation of this file.
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 '&amp;').
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]