[libxml++] Add Node::add_child_with_new_ns()
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxml++] Add Node::add_child_with_new_ns()
- Date: Fri, 10 Oct 2014 15:08:33 +0000 (UTC)
commit 47b2b269cae471f2480efebbe890588cc6a65506
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Fri Oct 10 16:59:52 2014 +0200
Add Node::add_child_with_new_ns()
* libxml++/nodes/node.[h|cc]: Add add_child_with_new_ns() (*2) and
add_child_before_with_new_ns(). Bug #737682.
libxml++/nodes/node.cc | 102 +++++++++++++++++++++++++++++++++++++-----------
libxml++/nodes/node.h | 66 +++++++++++++++++++++++++++++-
2 files changed, 142 insertions(+), 26 deletions(-)
---
diff --git a/libxml++/nodes/node.cc b/libxml++/nodes/node.cc
index c35bd16..5664f3b 100644
--- a/libxml++/nodes/node.cc
+++ b/libxml++/nodes/node.cc
@@ -111,6 +111,18 @@ Glib::ustring eval_common_to_string(const Glib::ustring& xpath,
return Glib::ustring();
}
+// Common part of all add_child*() methods.
+xmlpp::Element* add_child_common(const Glib::ustring& name, xmlNode* child, xmlNode* node)
+{
+ if (!node)
+ {
+ xmlFreeNode(child);
+ throw xmlpp::internal_error("Could not add child element node " + name);
+ }
+ xmlpp::Node::create_wrapper(node);
+ return static_cast<xmlpp::Element*>(node->_private);
+}
+
} // anonymous namespace
namespace xmlpp
@@ -229,49 +241,63 @@ Element* Node::add_child(const Glib::ustring& name,
{
_xmlNode* child = create_new_child_node(name, ns_prefix);
_xmlNode* node = xmlAddChild(impl_, child);
- if (!node)
- {
- xmlFreeNode(child);
- throw internal_error("Could not add child element node " + name);
- }
- Node::create_wrapper(node);
- return static_cast<Element*>(node->_private);
+ return add_child_common(name, child, node);
}
Element* Node::add_child(xmlpp::Node* previous_sibling,
const Glib::ustring& name,
const Glib::ustring& ns_prefix)
{
- if(!previous_sibling)
+ if (!previous_sibling)
return 0;
_xmlNode* child = create_new_child_node(name, ns_prefix);
_xmlNode* node = xmlAddNextSibling(previous_sibling->cobj(), child);
- if (!node)
- {
- xmlFreeNode(child);
- throw internal_error("Could not add child element node " + name);
- }
- Node::create_wrapper(node);
- return static_cast<Element*>(node->_private);
+ return add_child_common(name, child, node);
}
Element* Node::add_child_before(xmlpp::Node* next_sibling,
const Glib::ustring& name,
const Glib::ustring& ns_prefix)
{
- if(!next_sibling)
+ if (!next_sibling)
return 0;
_xmlNode* child = create_new_child_node(name, ns_prefix);
_xmlNode* node = xmlAddPrevSibling(next_sibling->cobj(), child);
- if (!node)
- {
- xmlFreeNode(child);
- throw internal_error("Could not add child element node " + name);
- }
- Node::create_wrapper(node);
- return static_cast<Element*>(node->_private);
+ return add_child_common(name, child, node);
+}
+
+Element* Node::add_child_with_new_ns(const Glib::ustring& name,
+ const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix)
+{
+ _xmlNode* child = create_new_child_node_with_new_ns(name, ns_uri, ns_prefix);
+ _xmlNode* node = xmlAddChild(impl_, child);
+ return add_child_common(name, child, node);
+}
+
+Element* Node::add_child_with_new_ns(xmlpp::Node* previous_sibling,
+ const Glib::ustring& name,
+ const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix)
+{
+ if (!previous_sibling)
+ return 0;
+
+ _xmlNode* child = create_new_child_node_with_new_ns(name, ns_uri, ns_prefix);
+ _xmlNode* node = xmlAddNextSibling(previous_sibling->cobj(), child);
+ return add_child_common(name, child, node);
+}
+
+Element* Node::add_child_before_with_new_ns(xmlpp::Node* next_sibling,
+ const Glib::ustring& name,
+ const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix)
+{
+ if (!next_sibling)
+ return 0;
+
+ _xmlNode* child = create_new_child_node_with_new_ns(name, ns_uri, ns_prefix);
+ _xmlNode* node = xmlAddPrevSibling(next_sibling->cobj(), child);
+ return add_child_common(name, child, node);
}
_xmlNode* Node::create_new_child_node(const Glib::ustring& name, const Glib::ustring& ns_prefix)
@@ -301,6 +327,36 @@ _xmlNode* Node::create_new_child_node(const Glib::ustring& name, const Glib::ust
return xmlNewNode(ns, (const xmlChar*)name.c_str());
}
+_xmlNode* Node::create_new_child_node_with_new_ns(const Glib::ustring& name,
+ const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix)
+{
+ if (impl_->type != XML_ELEMENT_NODE)
+ throw internal_error("You can only add child nodes to element nodes.");
+
+ xmlNode* child = xmlNewNode(0, (const xmlChar*)name.c_str());
+ if (!child)
+ throw internal_error("Could not create new element node.");
+
+ xmlNs* ns = xmlNewNs(child, (const xmlChar*)(ns_uri.empty() ? 0 : ns_uri.c_str()),
+ (const xmlChar*)(ns_prefix.empty() ? 0 : ns_prefix.c_str()) );
+ // xmlNewNs() does not create a namespace node for the predefined xml prefix.
+ // It's usually defined in the document and not in any specific node.
+ if (!ns && ns_prefix == "xml")
+ {
+ ns = xmlSearchNs(impl_->doc, impl_, (const xmlChar*)ns_prefix.c_str());
+ if (ns && (ns_uri != (ns->href ? (const char*)ns->href : "")))
+ ns = 0;
+ }
+ if (!ns)
+ {
+ xmlFreeNode(child);
+ throw internal_error("Could not create new namespace node.");
+ }
+
+ xmlSetNs(child, ns);
+
+ return child;
+}
void Node::remove_child(Node* node)
{
diff --git a/libxml++/nodes/node.h b/libxml++/nodes/node.h
index 6a02ecf..92a5fbe 100644
--- a/libxml++/nodes/node.h
+++ b/libxml++/nodes/node.h
@@ -158,7 +158,8 @@ public:
* @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 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.
+ * @throws xmlpp::internal_error If this node is not an element node,
+ * or the child node cannot be created.
*/
Element* add_child(const Glib::ustring& name,
const Glib::ustring& ns_prefix = Glib::ustring());
@@ -173,7 +174,8 @@ public:
* @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 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.
+ * @throws xmlpp::internal_error If this node is not an element node,
+ * or the child node cannot be created.
*/
Element* add_child(xmlpp::Node* previous_sibling, const Glib::ustring& name,
const Glib::ustring& ns_prefix = Glib::ustring());
@@ -188,11 +190,65 @@ public:
* @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 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.
+ * @throws xmlpp::internal_error If this node is not an element node,
+ * or the child node cannot be created.
*/
Element* add_child_before(xmlpp::Node* next_sibling, const Glib::ustring& name,
const Glib::ustring& ns_prefix = Glib::ustring());
+ /** Add a child element to this node.
+ * This node must be an element node.
+ *
+ * @newin{2,38}
+ *
+ * @param name The new node name.
+ * @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 prefix of the node's namespace. If no prefix is specified
+ * then the namespace URI will be the default namespace.
+ * @returns The newly-created element.
+ * @throws xmlpp::internal_error If this node is not an element node,
+ * or the child node or the namespace node cannot be created.
+ */
+ Element* add_child_with_new_ns(const Glib::ustring& name,
+ const Glib::ustring& ns_uri, 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,38}
+ *
+ * @param previous_sibling An existing child node.
+ * @param name The new node name.
+ * @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 prefix of the node's namespace. If no prefix is specified
+ * then the namespace URI will be the default namespace.
+ * @returns The newly-created element.
+ * @throws xmlpp::internal_error If this node is not an element node,
+ * or the child node or the namespace node cannot be created.
+ */
+ Element* add_child_with_new_ns(xmlpp::Node* previous_sibling, const Glib::ustring& name,
+ const Glib::ustring& ns_uri, 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,38}
+ *
+ * @param next_sibling An existing child node.
+ * @param name The new node name.
+ * @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 prefix of the node's namespace. If no prefix is specified
+ * then the namespace URI will be the default namespace.
+ * @returns The newly-created element.
+ * @throws xmlpp::internal_error If this node is not an element node,
+ * or the child node or the namespace node cannot be created.
+ */
+ Element* add_child_before_with_new_ns(xmlpp::Node* next_sibling, const Glib::ustring& name,
+ const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring());
+
/** Remove the child node.
* @param node The child node to remove. This Node will be deleted and therefore unusable after calling
this method.
*/
@@ -352,6 +408,10 @@ protected:
///Create the C instance ready to be added to the parent node.
_xmlNode* create_new_child_node(const Glib::ustring& name, const Glib::ustring& ns_prefix);
+ ///Create the C instance ready to be added to the parent node.
+ _xmlNode* create_new_child_node_with_new_ns(const Glib::ustring& name,
+ const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix);
+
private:
_xmlNode* impl_;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]