diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pugixml.cpp | 103 | ||||
-rw-r--r-- | src/pugixml.hpp | 52 |
2 files changed, 154 insertions, 1 deletions
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 <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <assert.h>
// For placement new
#include <new>
@@ -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 @@ -922,6 +922,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) * * \param type - node type @@ -948,6 +974,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 * * \param a - attribute to be removed |