[libxml++] Element, Node: Improve the error handling.



commit a0483871fb13a5543c4e54f7d7ec25cc133ac32e
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Thu Aug 2 18:38:42 2012 +0200

    Element, Node: Improve the error handling.
    
    * libxml++/nodes/element.[h|cc]:
    * libxml++/nodes/node.[h|cc]: Check more return codes from libxml2 functions.
    Improve the description of errors in the reference documentation. Bug #635846.

 ChangeLog                 |    8 +++
 libxml++/nodes/element.cc |  111 +++++++++++++++++++++++++++++++--------------
 libxml++/nodes/element.h  |   18 ++++++-
 libxml++/nodes/node.cc    |   50 ++++++++++++--------
 libxml++/nodes/node.h     |   63 ++++++++++++++++++-------
 5 files changed, 174 insertions(+), 76 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f3a0d09..04e7ab7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-08-02  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+ 
+	Element, Node: Improve the error handling.
+
+	* libxml++/nodes/element.[h|cc]:
+	* libxml++/nodes/node.[h|cc]: Check more return codes from libxml2 functions.
+	Improve the description of errors in the reference documentation. Bug #635846.
+
 2.35.3:
 
 2012-06-19  Kjell Ahlstedt  <kjell ahlstedt bredband net>
diff --git a/libxml++/nodes/element.cc b/libxml++/nodes/element.cc
index 2e3f786..0fac9fb 100644
--- a/libxml++/nodes/element.cc
+++ b/libxml++/nodes/element.cc
@@ -157,13 +157,18 @@ TextNode* Element::add_child_text(const Glib::ustring& content)
 {
   if(cobj()->type == XML_ELEMENT_NODE)
   {
-     xmlNode* node = xmlNewText((const xmlChar*)content.c_str());
+    xmlNode* child = xmlNewText((const xmlChar*)content.c_str());
 
-     // Use the result, because node can be freed when merging text nodes:
-     node = xmlAddChild(cobj(), node); 
-
-     Node::create_wrapper(node);
-     return static_cast<TextNode*>(node->_private);
+    // Use the result, because child can be freed when merging text nodes:
+    xmlNode* node = xmlAddChild(cobj(), child);
+    if (!node)
+    {
+      if (child)
+        xmlFreeNode(child);
+      throw internal_error("Could not add text node \"" + content + "\"");
+    }
+    Node::create_wrapper(node);
+    return static_cast<TextNode*>(node->_private);
   }
   return 0;
 }
@@ -175,13 +180,18 @@ TextNode* Element::add_child_text(xmlpp::Node* previous_sibling, const Glib::ust
 
   if(cobj()->type == XML_ELEMENT_NODE)
   {
-     xmlNode* node = xmlNewText((const xmlChar*)content.c_str());
+    xmlNode* child = xmlNewText((const xmlChar*)content.c_str());
 
-     // Use the result, because node can be freed when merging text nodes:
-     node = xmlAddNextSibling(previous_sibling->cobj(), node); 
-
-     Node::create_wrapper(node);
-     return static_cast<TextNode*>(node->_private);
+    // Use the result, because child can be freed when merging text nodes:
+    xmlNode* node = xmlAddNextSibling(previous_sibling->cobj(), child);
+    if (!node)
+    {
+      if (child)
+        xmlFreeNode(child);
+      throw internal_error("Could not add text node \"" + content + "\"");
+    }
+    Node::create_wrapper(node);
+    return static_cast<TextNode*>(node->_private);
   }
   return 0;
 }
@@ -193,13 +203,18 @@ TextNode* Element::add_child_text_before(xmlpp::Node* next_sibling, const Glib::
 
   if(cobj()->type == XML_ELEMENT_NODE)
   {
-     xmlNode* node = xmlNewText((const xmlChar*)content.c_str());
-
-     // Use the result, because node can be freed when merging text nodes:
-     node = xmlAddPrevSibling(next_sibling->cobj(), node); 
+    xmlNode* child = xmlNewText((const xmlChar*)content.c_str());
 
-     Node::create_wrapper(node);
-     return static_cast<TextNode*>(node->_private);
+    // Use the result, because child can be freed when merging text nodes:
+    xmlNode* node = xmlAddPrevSibling(next_sibling->cobj(), child);
+    if (!node)
+    {
+      if (child)
+        xmlFreeNode(child);
+      throw internal_error("Could not add text node \"" + content + "\"");
+    }
+    Node::create_wrapper(node);
+    return static_cast<TextNode*>(node->_private);
   }
   return 0;
 }
@@ -212,9 +227,12 @@ bool Element::has_child_text() const
 void Element::set_namespace_declaration(const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix)
 {
   //Create a new namespace declaration for this element:
-  xmlNewNs(cobj(), (const xmlChar*)(ns_uri.empty() ? 0 : ns_uri.c_str()),
-                   (const xmlChar*)(ns_prefix.empty() ? 0 : ns_prefix.c_str()) );
-  //We ignore the returned xmlNs*. Hopefully this is owned by the node. murrayc.
+  xmlNs* ns = xmlNewNs(cobj(), (const xmlChar*)(ns_uri.empty() ? 0 : ns_uri.c_str()),
+                       (const xmlChar*)(ns_prefix.empty() ? 0 : ns_prefix.c_str()) );
+  if (!ns)
+    throw exception("Could not add namespace declaration with URI=" + ns_uri +
+                    ", prefix=" + ns_prefix);
+  //We ignore the returned xmlNs*. It's owned by the XML_ELEMENT_NODE.
 }
 
 Glib::ustring Element::get_namespace_uri_for_prefix(const Glib::ustring& ns_prefix) const
@@ -236,10 +254,16 @@ Glib::ustring Element::get_namespace_uri_for_prefix(const Glib::ustring& ns_pref
 
 CommentNode* Element::add_child_comment(const Glib::ustring& content)
 {
-  xmlNode* node = xmlNewComment((const xmlChar*)content.c_str());
+  xmlNode* child = xmlNewComment((const xmlChar*)content.c_str());
  
-  // Use the result, because node can be freed when merging text nodes:
-  node = xmlAddChild(cobj(), node);
+  // Use the result, because child can be freed when merging text nodes:
+  xmlNode* node = xmlAddChild(cobj(), child);
+  if (!node)
+  {
+    if (child)
+      xmlFreeNode(child);
+    throw internal_error("Could not add comment node \"" + content + "\"");
+  }
   Node::create_wrapper(node);
   return static_cast<CommentNode*>(node->_private);
 }
@@ -247,8 +271,14 @@ CommentNode* Element::add_child_comment(const Glib::ustring& content)
 
 CdataNode* Element::add_child_cdata(const Glib::ustring& content)
 {
-  xmlNode* node = xmlNewCDataBlock(cobj()->doc, (const xmlChar*)content.c_str(), content.bytes());
-  node = xmlAddChild(cobj(), node);
+  xmlNode* child = xmlNewCDataBlock(cobj()->doc, (const xmlChar*)content.c_str(), content.bytes());
+  xmlNode* node = xmlAddChild(cobj(), child);
+  if (!node)
+  {
+    if (child)
+      xmlFreeNode(child);
+    throw internal_error("Could not add CDATA node \"" + content + "\"");
+  }
   Node::create_wrapper(node);
   return static_cast<CdataNode*>(node->_private);
 }
@@ -262,24 +292,35 @@ EntityReference* Element::add_child_entity_reference(const Glib::ustring& name)
 
   // Is it an entity reference or a character reference?
   // libxml uses xmlNode::type == XML_ENTITY_REF_NODE for both.
-  xmlNode* node = 0;
+  xmlNode* child = 0;
   if (extended_name[ichar] == '#')
-    node = xmlNewCharRef(cobj()->doc, (const xmlChar*)name.c_str());
+    child = xmlNewCharRef(cobj()->doc, (const xmlChar*)name.c_str());
   else
-    node = xmlNewReference(cobj()->doc, (const xmlChar*)name.c_str());
-  node = xmlAddChild(cobj(), node);
+    child = xmlNewReference(cobj()->doc, (const xmlChar*)name.c_str());
+  xmlNode* node = xmlAddChild(cobj(), child);
+  if (!node)
+  {
+    if (child)
+      xmlFreeNode(child);
+    throw internal_error("Could not add entity reference node " + name);
+  }
   Node::create_wrapper(node);
-  return node ? static_cast<EntityReference*>(node->_private) : 0;
+  return static_cast<EntityReference*>(node->_private);
 }
 
 ProcessingInstructionNode* Element::add_child_processing_instruction(
   const Glib::ustring& name, const Glib::ustring& content)
 {
-  xmlNode* node = xmlNewDocPI(cobj()->doc, (const xmlChar*)name.c_str(), (const xmlChar*)content.c_str());
-  node = xmlAddChild(cobj(), node);
+  xmlNode* child = xmlNewDocPI(cobj()->doc, (const xmlChar*)name.c_str(), (const xmlChar*)content.c_str());
+  xmlNode* node = xmlAddChild(cobj(), child);
+  if (!node)
+  {
+    if (child)
+      xmlFreeNode(child);
+    throw internal_error("Could not add processing instruction node " + name);
+  }
   Node::create_wrapper(node);
-  return node ? static_cast<ProcessingInstructionNode*>(node->_private) : 0;
+  return static_cast<ProcessingInstructionNode*>(node->_private);
 }
 
-
 } //namespace xmlpp
diff --git a/libxml++/nodes/element.h b/libxml++/nodes/element.h
index c9e3082..a727989 100644
--- a/libxml++/nodes/element.h
+++ b/libxml++/nodes/element.h
@@ -29,8 +29,12 @@ public:
   typedef std::list<Attribute*> AttributeList;
 
   /** This adds a namespace declaration to this node which will apply to this node and all children.
-   * @param ns_uri The namespace to associate with the prefix, or to use as the default namespace if no prefix is specified.
-   * @param ns_prefix The namespace prefix. If no prefix is specified then the namespace URI will be the default namespace.
+   * @param ns_uri The namespace to associate with the prefix,
+   *               or to use as the default namespace if no prefix is specified.
+   * @param ns_prefix The namespace prefix. If no prefix is specified then the
+   *                  namespace URI will be the default namespace.
+   * @throws xmlpp::exception If a new namespace node cannot be created,
+   *         e.g. because a namespace with the same prefix already exists.
    */
   void set_namespace_declaration(const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring());
 
@@ -75,7 +79,7 @@ public:
    * @param value The new value for the attribute
    * @param ns_prefix Namespace prefix. If the prefix has not been declared then this method will throw an exception.
    * @return The attribute that was changed, or 0 is no suitable Attribute was found.
-   * @throws exception
+   * @throws xmlpp::exception
    */
   Attribute* set_attribute(const Glib::ustring& name, const Glib::ustring& value,
                            const Glib::ustring& ns_prefix = Glib::ustring());
@@ -103,6 +107,7 @@ public:
   /** Append a new text node.
    * @param content The text. This should be unescaped - see ContentNode::set_content().
    * @returns The new text node.
+   * @throws xmlpp::internal_error
    */
   TextNode* add_child_text(const Glib::ustring& content = Glib::ustring());
 
@@ -113,6 +118,7 @@ public:
    * @param previous_sibling An existing child node.
    * @param content The text. This should be unescaped - see ContentNode::set_content().
    * @returns The new text node.
+   * @throws xmlpp::internal_error
    */
   TextNode* add_child_text(xmlpp::Node* previous_sibling, const Glib::ustring& content = Glib::ustring());
 
@@ -123,12 +129,14 @@ public:
    * @param next_sibling An existing child node.
    * @param content The text. This should be unescaped - see ContentNode::set_content().
    * @returns The new text node.
+   * @throws xmlpp::internal_error
    */
   TextNode* add_child_text_before(xmlpp::Node* next_sibling, const Glib::ustring& content = Glib::ustring());
 
   /** Set the text of the first text node, adding one if necessary.
    * This is a convenience method, meant as an alternative to iterating over all the child nodes to find the first suitable node then and setting the text directly.
    * @param content The text. This should be unescaped - see ContentNode::set_content().
+   * @throws xmlpp::internal_error
    */
   void set_child_text(const Glib::ustring& content);
 
@@ -141,12 +149,14 @@ public:
   /** Append a new comment node.
    * @param content The text. This should be unescaped - see ContentNode::set_content().
    * @returns The new comment node.
+   * @throws xmlpp::internal_error
    */
   CommentNode* add_child_comment(const Glib::ustring& content);
 
   /** Append a new CDATA node.
    * @param content The raw text.
    * @returns The new CDATA node.
+   * @throws xmlpp::internal_error
    */
   CdataNode* add_child_cdata(const Glib::ustring& content);
 
@@ -162,6 +172,7 @@ public:
    *
    * @param name The name of the entity.
    * @returns The new entity reference node.
+   * @throws xmlpp::internal_error
    */
   EntityReference* add_child_entity_reference(const Glib::ustring& name);
 
@@ -172,6 +183,7 @@ public:
    * @param name The name of the application to which the instruction is directed.
    * @param content The content of the instruction. This should be unescaped - see ContentNode::set_content().
    * @returns The new processing instruction node.
+   * @throws xmlpp::internal_error
    */
   ProcessingInstructionNode* add_child_processing_instruction(
     const Glib::ustring& name, const Glib::ustring& content);
diff --git a/libxml++/nodes/node.cc b/libxml++/nodes/node.cc
index 8f2344a..0ba6822 100644
--- a/libxml++/nodes/node.cc
+++ b/libxml++/nodes/node.cc
@@ -30,6 +30,8 @@ xmlXPathObject* eval_common(const Glib::ustring& xpath,
   xmlpp::XPathResultType* result_type, xmlNode* node)
 {
   xmlXPathContext* ctxt = xmlXPathNewContext(node->doc);
+  if (!ctxt)
+    throw xmlpp::internal_error("Could not create XPath context for " + xpath);
   ctxt->node = node;
 
   if (namespaces)
@@ -221,13 +223,13 @@ Element* Node::add_child(const Glib::ustring& name,
                          const Glib::ustring& ns_prefix)
 {
   _xmlNode* child = create_new_child_node(name, ns_prefix);
-  if(!child)
-    return 0;
-
   _xmlNode* node = xmlAddChild(impl_, child);
-  if(!node)
-    return 0;
- 
+  if (!node)
+  {
+    if (child)
+      xmlFreeNode(child);
+    throw internal_error("Could not add child element node " + name);
+  }
   Node::create_wrapper(node);
   return static_cast<Element*>(node->_private);
 }
@@ -240,13 +242,13 @@ Element* Node::add_child(xmlpp::Node* previous_sibling,
     return 0;
 
   _xmlNode* child = create_new_child_node(name, ns_prefix);
-  if(!child)
-    return 0;
-
   _xmlNode* node = xmlAddNextSibling(previous_sibling->cobj(), child);
-  if(!node)
-    return 0;
-
+  if (!node)
+  {
+    if (child)
+      xmlFreeNode(child);
+    throw internal_error("Could not add child element node " + name);
+  }
   Node::create_wrapper(node);
   return static_cast<Element*>(node->_private);
 }
@@ -259,13 +261,13 @@ Element* Node::add_child_before(xmlpp::Node* next_sibling,
     return 0;
 
   _xmlNode* child = create_new_child_node(name, ns_prefix);
-  if(!child)
-    return 0;
-
   _xmlNode* node = xmlAddPrevSibling(next_sibling->cobj(), child);
-  if(!node)
-    return 0;
-
+  if (!node)
+  {
+    if (child)
+      xmlFreeNode(child);
+    throw internal_error("Could not add child element node " + name);
+  }
   Node::create_wrapper(node);
   return static_cast<Element*>(node->_private);
 }
@@ -302,7 +304,8 @@ void Node::remove_child(Node* node)
 {
   //TODO: Allow a node to be removed without deleting it, to allow it to be moved?
   //This would require a more complex memory management API.
-  
+  if (!node)
+    return;
   xmlNode* cnode = node->cobj();
   Node::free_wrappers(cnode); //This delete the C++ node (not this) itself.
   xmlUnlinkNode(cnode);
@@ -311,11 +314,14 @@ void Node::remove_child(Node* node)
 
 Node* Node::import_node(const Node* node, bool recursive)
 {
+  if (!node)
+    return 0;
+
   //Create the node, by copying:
   xmlNode* imported_node = xmlDocCopyNode(const_cast<xmlNode*>(node->cobj()), impl_->doc, recursive);
   if (!imported_node)
   {
-    throw exception("Unable to import node");
+    throw exception("Unable to copy the node that shall be imported");
   }
 
   if (imported_node->type == XML_ATTRIBUTE_NODE && impl_->type == XML_ELEMENT_NODE)
@@ -446,6 +452,8 @@ static NodeSet find_impl(xmlXPathContext* ctxt, const Glib::ustring& xpath)
 NodeSet Node::find(const Glib::ustring& xpath) const
 {
   xmlXPathContext* ctxt = xmlXPathNewContext(impl_->doc);
+  if (!ctxt)
+    throw internal_error("Could not create XPath context for " + xpath);
   ctxt->node = impl_;
   
   return find_impl(ctxt, xpath);
@@ -455,6 +463,8 @@ NodeSet Node::find(const Glib::ustring& xpath,
 		   const PrefixNsMap& namespaces) const
 {
   xmlXPathContext* ctxt = xmlXPathNewContext(impl_->doc);
+  if (!ctxt)
+    throw internal_error("Could not create XPath context for " + xpath);
   ctxt->node = impl_;
 
   for (PrefixNsMap::const_iterator it=namespaces.begin();
diff --git a/libxml++/nodes/node.h b/libxml++/nodes/node.h
index b54fdb3..a60107e 100644
--- a/libxml++/nodes/node.h
+++ b/libxml++/nodes/node.h
@@ -71,11 +71,18 @@ public:
   /** Set the namespace prefix used by the node.
    * If no such namespace prefix has been declared then this method will throw an exception.
    * @param ns_prefix The namespace prefix.
-   * @throws exception
+   * @throws xmlpp::exception
    */
   void set_namespace(const Glib::ustring& ns_prefix);
 
+  /** Get the namespace prefix of this node.
+   * @returns The node's namespace prefix. Can be an empty string.
+   */
   Glib::ustring get_namespace_prefix() const;
+
+  /** Get the namespace URI of this node.
+   * @returns The node's namespace URI. Can be an empty string.
+   */
   Glib::ustring get_namespace_uri() const;
 
   /** Discover at what line number this node occurs in the XML file.
@@ -84,44 +91,48 @@ public:
   int get_line() const;
   
   /** Get the parent element for this node.
-   * @returns The parent node
+   * @returns The parent node, or <tt>0</tt> if the node has no parent element.
    */
   const Element* get_parent() const;  
 
   /** Get the parent element for this node.
-   * @returns The parent node
+   * @returns The parent node, or <tt>0</tt> if the node has no parent element.
    */
   Element* get_parent();  
 
   /** Get the next sibling for this node.
-   * @returns The next sibling
+   * @returns The next sibling, or <tt>0</tt> if the node has no next sibling.
    */
   const Node* get_next_sibling() const;  
 
   /** Get the next sibling for this node.
-   * @returns The next sibling
+   * @returns The next sibling, or <tt>0</tt> if the node has no next sibling.
    */
   Node* get_next_sibling();  
 
   /** Get the previous sibling for this node .
-   * @returns The previous sibling
+   * @returns The previous sibling, or <tt>0</tt> if the node has no previous sibling.
    */
   const Node* get_previous_sibling() const;  
 
   /** Get the previous sibling for this node.
-   * @returns The previous sibling
+   * @returns The previous sibling, or <tt>0</tt> if the node has no previous sibling.
    */
   Node* get_previous_sibling();  
 
-  /** Get the first child of this node. You may optionally get the first child node which has a certain name.
-   * @returns The first child
+  /** Get the first child of this node.
+   * You may optionally get the first child node which has a certain name.
+   * @param name The name of the requested child node, or an empty string.
+   * @returns The first child, or <tt>0</tt> if no child node (with the specified name) exists.
    *
    * @newin{2,36}
    */
   const Node* get_first_child(const Glib::ustring& name = Glib::ustring()) const;
 
-  /** Get the first child of this node. You may optionally get the first child node which has a certain name.
-   * @returns The first child
+  /** Get the first child of this node.
+   * You may optionally get the first child node which has a certain name.
+   * @param name The name of the requested child node, or an empty string.
+   * @returns The first child, or <tt>0</tt> if no child node (with the specified name) exists.
    *
    * @newin{2,36}
    */
@@ -140,15 +151,18 @@ public:
   const NodeList get_children(const Glib::ustring& name = Glib::ustring()) const;
 
   /** Add a child element to this node.
+   * This node must be an element node.
    * @param name The new node name
    * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception.
    * @returns The newly-created element
-   * @throws exception
+   * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared.
+   * @throws xmlpp::internal_error If this node is not an element node.
    */
   Element* add_child(const Glib::ustring& name,
                      const Glib::ustring& ns_prefix = Glib::ustring());
 
   /** Add a child element to this node after the specified existing child node.
+   * This node must be an element node.
    *
    * @newin{2,24}
    *
@@ -156,12 +170,14 @@ public:
    * @param name The new node name
    * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception.
    * @returns The newly-created element
-   * @throws exception
+   * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared.
+   * @throws xmlpp::internal_error If this node is not an element node.
    */
   Element* add_child(xmlpp::Node* previous_sibling, const Glib::ustring& name,
                      const Glib::ustring& ns_prefix = Glib::ustring());
 
   /** Add a child element to this node before the specified existing child node.
+   * This node must be an element node.
    *
    * @newin{2,24}
    *
@@ -169,7 +185,8 @@ public:
    * @param name The new node name
    * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception.
    * @returns The newly-created element
-   * @throws exception
+   * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared.
+   * @throws xmlpp::internal_error If this node is not an element node.
    */
   Element* add_child_before(xmlpp::Node* next_sibling, const Glib::ustring& name,
                      const Glib::ustring& ns_prefix = Glib::ustring());
@@ -190,19 +207,21 @@ public:
    * @param recursive Whether to import the child nodes also. Defaults to true.
    * @returns Usually the newly created node, but adjacent text nodes are merged,
    *          and the old text node with merged contents is returned.
-   * @throws exception
+   * @throws xmlpp::exception
    */
   Node* import_node(const Node* node, bool recursive = true);
 
   
-  /** Return the XPath of this node.
+  /** Get the XPath of this node.
    * @result The XPath of the node.
    */
   Glib::ustring get_path() const;
 
   /** Find nodes from an XPath expression.
    * @param xpath The XPath of the nodes.
-   * @throws exception
+   * @returns The resulting NodeSet.
+   * @throws xmlpp::exception If the XPath expression cannot be evaluated.
+   * @throws xmlpp::internal_error If the result type is not nodeset.
    */
   NodeSet find(const Glib::ustring& xpath) const;
 
@@ -213,7 +232,9 @@ public:
   /** Find nodes from an XPath expression.
    * @param xpath The XPath of the nodes.
    * @param namespaces A map of namespace prefixes to namespace URIs to be used while finding.
-   * @throws exception
+   * @returns The resulting NodeSet.
+   * @throws xmlpp::exception If the XPath expression cannot be evaluated.
+   * @throws xmlpp::internal_error If the result type is not nodeset.
    */
   NodeSet find(const Glib::ustring& xpath, const PrefixNsMap& namespaces) const;
 
@@ -224,6 +245,7 @@ public:
    * @returns The value of the XPath expression. If the value is not of type boolean,
    *          it is converted to boolean.
    * @throws xmlpp::exception If the XPath expression cannot be evaluated.
+   * @throws xmlpp::internal_error
    *
    * @newin{2,36}
    */
@@ -238,6 +260,7 @@ public:
    * @returns The value of the XPath expression. If the value is not of type boolean,
    *          it is converted to boolean.
    * @throws xmlpp::exception If the XPath expression cannot be evaluated.
+   * @throws xmlpp::internal_error
    *
    * @newin{2,36}
    */
@@ -251,6 +274,7 @@ public:
    * @returns The value of the XPath expression. If the value is not of type number,
    *          it is converted to number.
    * @throws xmlpp::exception If the XPath expression cannot be evaluated.
+   * @throws xmlpp::internal_error
    *
    * @newin{2,36}
    */
@@ -264,6 +288,7 @@ public:
    * @returns The value of the XPath expression. If the value is not of type number,
    *          it is converted to number.
    * @throws xmlpp::exception If the XPath expression cannot be evaluated.
+   * @throws xmlpp::internal_error
    *
    * @newin{2,36}
    */
@@ -277,6 +302,7 @@ public:
    * @returns The value of the XPath expression. If the value is not of type string,
    *          it is converted to string.
    * @throws xmlpp::exception If the XPath expression cannot be evaluated.
+   * @throws xmlpp::internal_error
    *
    * @newin{2,36}
    */
@@ -290,6 +316,7 @@ public:
    * @returns The value of the XPath expression. If the value is not of type string,
    *          it is converted to string.
    * @throws xmlpp::exception If the XPath expression cannot be evaluated.
+   * @throws xmlpp::internal_error
    *
    * @newin{2,36}
    */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]