diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 90c48b2..01e8c84 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -6059,6 +6059,23 @@ namespace pugi
return true;
}
+ PUGI__FN bool xml_node::remove_attributes()
+ {
+ for(pugi::xml_attribute a: this->attributes())
+ {
+ if (!_root || !a._attr) return false;
+ if (!impl::is_attribute_of(a._attr, _root)) return false;
+
+ impl::xml_allocator& alloc = impl::get_allocator(_root);
+ if (!alloc.reserve()) return false;
+
+ impl::destroy_attribute(a._attr, alloc);
+ }
+ this->_root->first_attribute = nullptr;
+
+ return true;
+ }
+
PUGI__FN bool xml_node::remove_child(const char_t* name_)
{
return remove_child(child(name_));
@@ -6077,6 +6094,22 @@ namespace pugi
return true;
}
+ PUGI__FN bool xml_node::remove_children()
+ {
+ for (pugi::xml_node child: this->children())
+ {
+ if (!_root || !child._root || child._root->parent != _root) return false;
+
+ impl::xml_allocator& alloc = impl::get_allocator(_root);
+ if (!alloc.reserve()) return false;
+
+ impl::destroy_node(child._root, alloc);
+ }
+ this->_root->first_child = nullptr;
+
+ return true;
+ }
+
PUGI__FN xml_parse_result xml_node::append_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding)
{
// append_buffer is only valid for elements/documents
diff --git a/src/pugixml.hpp b/src/pugixml.hpp
index da8ff36..8986d2a 100644
--- a/src/pugixml.hpp
+++ b/src/pugixml.hpp
@@ -576,10 +576,16 @@ namespace pugi
bool remove_attribute(const xml_attribute& a);
bool remove_attribute(const char_t* name);
+ // Remove all attributes
+ bool remove_attributes();
+
// Remove specified child
bool remove_child(const xml_node& n);
bool remove_child(const char_t* name);
+ // Remove all children
+ bool remove_children();
+
// Parses buffer as an XML document fragment and appends all nodes as children of the current node.
// Copies/converts the buffer, so it may be deleted or changed after the function returns.
// Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory.
diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp
index 9696827..e0558d9 100644
--- a/tests/test_dom_modify.cpp
+++ b/tests/test_dom_modify.cpp
@@ -492,6 +492,18 @@ TEST_XML(dom_node_remove_attribute, "")
+{
+ xml_node node = doc.child(STR("node"));
+ xml_node child = node.child(STR("child"));
+
+ CHECK(child.remove_attributes());
+ CHECK_NODE(child, STR(""));
+
+ CHECK(node.remove_attributes());
+ CHECK_NODE(node, STR(""));
+}
+
TEST_XML(dom_node_prepend_child, "foo")
{
CHECK(xml_node().prepend_child() == xml_node());
@@ -707,6 +719,18 @@ TEST_XML(dom_node_remove_child, ""));
}
+TEST_XML(dom_node_remove_children, "")
+{
+ xml_node node = doc.child(STR("node"));
+ xml_node child = node.child(STR("child"));
+
+ CHECK(child.remove_children());
+ CHECK_NODE(child, STR(""));
+
+ CHECK(node.remove_children());
+ CHECK_NODE(node, STR(""));
+}
+
TEST_XML(dom_node_remove_child_complex, "")
{
CHECK(doc.child(STR("node")).remove_child(STR("n1")));