From 355d0f06971002efc2aca5a3bf2a8ecebef9b7d6 Mon Sep 17 00:00:00 2001 From: "arseny.kapoulkine" Date: Thu, 8 Jan 2009 19:30:42 +0000 Subject: Implemented attribute and node copying git-svn-id: http://pugixml.googlecode.com/svn/trunk@106 99668b35-9821-0410-8761-19e4c4f06640 --- src/pugixml.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/pugixml.hpp | 52 ++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index ad57086..ccaec6a 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -16,6 +16,7 @@ #include #include #include +#include // For placement new #include @@ -1597,7 +1598,50 @@ namespace } default: - ; + assert(false); + } + } + + void recursive_copy_skip(xml_node& dest, const xml_node& source, const xml_node& skip) + { + assert(dest.type() == source.type()); + + switch (source.type()) + { + case node_element: + { + dest.set_name(source.name()); + + for (xml_attribute a = source.first_attribute(); a; a = a.next_attribute()) + dest.append_attribute(a.name()).set_value(a.value()); + + for (xml_node c = source.first_child(); c; c = c.next_sibling()) + { + if (c == skip) continue; + + xml_node cc = dest.append_child(c.type()); + assert(cc); + + recursive_copy_skip(cc, c, skip); + } + + break; + } + + case node_pcdata: + case node_cdata: + case node_comment: + case node_pi: + dest.set_value(source.value()); + break; + + case node_declaration: + dest.set_name(source.name()); + dest.set_value(source.value()); + break; + + default: + assert(false); } } } @@ -2220,6 +2264,36 @@ namespace pugi return a; } + xml_attribute xml_node::append_copy(const xml_attribute& proto) + { + if (!proto) return xml_attribute(); + + xml_attribute result = append_attribute(proto.name()); + result.set_value(proto.value()); + + return result; + } + + xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr) + { + if (!proto) return xml_attribute(); + + xml_attribute result = insert_attribute_after(proto.name(), attr); + result.set_value(proto.value()); + + return result; + } + + xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr) + { + if (!proto) return xml_attribute(); + + xml_attribute result = insert_attribute_before(proto.name(), attr); + result.set_value(proto.value()); + + return result; + } + xml_node xml_node::append_child(xml_node_type type) { if ((this->type() != node_element && this->type() != node_document) || type == node_document || type == node_null) return xml_node(); @@ -2267,6 +2341,33 @@ namespace pugi return n; } + xml_node xml_node::append_copy(const xml_node& proto) + { + xml_node result = append_child(proto.type()); + + if (result) recursive_copy_skip(result, proto, result); + + return result; + } + + xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node) + { + xml_node result = insert_child_after(proto.type(), node); + + if (result) recursive_copy_skip(result, proto, result); + + return result; + } + + xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node) + { + xml_node result = insert_child_before(proto.type(), node); + + if (result) recursive_copy_skip(result, proto, result); + + return result; + } + void xml_node::remove_attribute(const char* name) { remove_attribute(attribute(name)); diff --git a/src/pugixml.hpp b/src/pugixml.hpp index fd25077..2b014c9 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -921,6 +921,32 @@ namespace pugi */ xml_attribute insert_attribute_before(const char* name, const xml_attribute& attr); + /** + * Add a copy of the specified attribute (for element nodes) + * + * \param proto - attribute prototype which is to be copied + * \return inserted attribute, or empty attribute if there was an error (wrong node type) + */ + xml_attribute append_copy(const xml_attribute& proto); + + /** + * Insert a copy of the specified attribute after \a attr (for element nodes) + * + * \param proto - attribute prototype which is to be copied + * \param attr - attribute to insert a new one after + * \return inserted attribute, or empty attribute if there was an error (wrong node type, or attr does not belong to node) + */ + xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr); + + /** + * Insert a copy of the specified attribute before \a attr (for element nodes) + * + * \param proto - attribute prototype which is to be copied + * \param attr - attribute to insert a new one before + * \return inserted attribute, or empty attribute if there was an error (wrong node type, or attr does not belong to node) + */ + xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr); + /** * Add child node with specified type (for element nodes) * @@ -947,6 +973,32 @@ namespace pugi */ xml_node insert_child_before(xml_node_type type, const xml_node& node); + /** + * Add a copy of the specified node as a child (for element nodes) + * + * \param proto - node prototype which is to be copied + * \return inserted node, or empty node if there was an error (wrong node type) + */ + xml_node append_copy(const xml_node& proto); + + /** + * Insert a copy of the specified node after \a node (for element nodes) + * + * \param proto - node prototype which is to be copied + * \param node - node to insert a new one after + * \return inserted node, or empty node if there was an error (wrong node type, or \a node is not a child of this node) + */ + xml_node insert_copy_after(const xml_node& proto, const xml_node& node); + + /** + * Insert a copy of the specified node before \a node (for element nodes) + * + * \param proto - node prototype which is to be copied + * \param node - node to insert a new one before + * \return inserted node, or empty node if there was an error (wrong node type, or \a node is not a child of this node) + */ + xml_node insert_copy_before(const xml_node& proto, const xml_node& node); + /** * Remove specified attribute * -- cgit v1.2.3