mirror of
https://github.com/zeux/pugixml.git
synced 2025-01-13 17:37:58 +08:00
feat: add remove_attributes() and remove_children() (#296)
These functions remove all attributes / child nodes in bulk which is faster than removing them one at a time.
This commit is contained in:
parent
ccb63a9186
commit
fd7326fb91
@ -1378,16 +1378,18 @@ include::samples/modify_add.cpp[tags=code]
|
|||||||
[[modify.remove]]
|
[[modify.remove]]
|
||||||
=== Removing nodes/attributes
|
=== Removing nodes/attributes
|
||||||
|
|
||||||
[[xml_node::remove_attribute]][[xml_node::remove_child]]
|
[[xml_node::remove_attribute]][[xml_node::remove_attributes]][[xml_node::remove_child]][[xml_node::remove_children]]
|
||||||
If you do not want your document to contain some node or attribute, you can remove it with one of the following functions:
|
If you do not want your document to contain some node or attribute, you can remove it with one of the following functions:
|
||||||
|
|
||||||
[source]
|
[source]
|
||||||
----
|
----
|
||||||
bool xml_node::remove_attribute(const xml_attribute& a);
|
bool xml_node::remove_attribute(const xml_attribute& a);
|
||||||
|
bool xml_node::remove_attributes();
|
||||||
bool xml_node::remove_child(const xml_node& n);
|
bool xml_node::remove_child(const xml_node& n);
|
||||||
|
bool xml_node::remove_children();
|
||||||
----
|
----
|
||||||
|
|
||||||
`remove_attribute` removes the attribute from the attribute list of the node, and returns the operation result. `remove_child` removes the child node with the entire subtree (including all descendant nodes and attributes) from the document, and returns the operation result. Removing fails if one of the following is true:
|
`remove_attribute` removes the attribute from the attribute list of the node, and returns the operation result. `remove_child` removes the child node with the entire subtree (including all descendant nodes and attributes) from the document, and returns the operation result. `remove_attributes` removes all the attributes of the node, and returns the operation result. `remove_children` removes all the child nodes of the node, and returns the operation result. Removing fails if one of the following is true:
|
||||||
|
|
||||||
* The node the function is called on is null;
|
* The node the function is called on is null;
|
||||||
* The attribute/node to be removed is null;
|
* The attribute/node to be removed is null;
|
||||||
@ -2868,8 +2870,10 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
|||||||
|
|
||||||
bool +++<a href="#xml_node::remove_attribute">remove_attribute</a>+++(const xml_attribute& a);
|
bool +++<a href="#xml_node::remove_attribute">remove_attribute</a>+++(const xml_attribute& a);
|
||||||
bool +++<a href="#xml_node::remove_attribute">remove_attribute</a>+++(const char_t* name);
|
bool +++<a href="#xml_node::remove_attribute">remove_attribute</a>+++(const char_t* name);
|
||||||
|
bool +++<a href="#xml_node::remove_attributes">remove_attributes</a>+++();
|
||||||
bool +++<a href="#xml_node::remove_child">remove_child</a>+++(const xml_node& n);
|
bool +++<a href="#xml_node::remove_child">remove_child</a>+++(const xml_node& n);
|
||||||
bool +++<a href="#xml_node::remove_child">remove_child</a>+++(const char_t* name);
|
bool +++<a href="#xml_node::remove_child">remove_child</a>+++(const char_t* name);
|
||||||
|
bool +++<a href="#xml_node::remove_children">remove_children</a>+++();
|
||||||
|
|
||||||
xml_parse_result +++<a href="#xml_node::append_buffer">append_buffer</a>+++(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
|
xml_parse_result +++<a href="#xml_node::append_buffer">append_buffer</a>+++(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
|
||||||
|
|
||||||
|
@ -6059,6 +6059,27 @@ namespace pugi
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PUGI__FN bool xml_node::remove_attributes()
|
||||||
|
{
|
||||||
|
if (!_root) return false;
|
||||||
|
|
||||||
|
impl::xml_allocator& alloc = impl::get_allocator(_root);
|
||||||
|
if (!alloc.reserve()) return false;
|
||||||
|
|
||||||
|
for (xml_attribute_struct* attr = _root->first_attribute; attr;)
|
||||||
|
{
|
||||||
|
xml_attribute_struct* next = attr->next_attribute;
|
||||||
|
|
||||||
|
impl::destroy_attribute(attr, alloc);
|
||||||
|
|
||||||
|
attr = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
_root->first_attribute = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
PUGI__FN bool xml_node::remove_child(const char_t* name_)
|
PUGI__FN bool xml_node::remove_child(const char_t* name_)
|
||||||
{
|
{
|
||||||
return remove_child(child(name_));
|
return remove_child(child(name_));
|
||||||
@ -6077,6 +6098,27 @@ namespace pugi
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PUGI__FN bool xml_node::remove_children()
|
||||||
|
{
|
||||||
|
if (!_root) return false;
|
||||||
|
|
||||||
|
impl::xml_allocator& alloc = impl::get_allocator(_root);
|
||||||
|
if (!alloc.reserve()) return false;
|
||||||
|
|
||||||
|
for (xml_node_struct* child = _root->first_child; child; )
|
||||||
|
{
|
||||||
|
xml_node_struct* next = child->next_sibling;
|
||||||
|
|
||||||
|
destroy_node(child, alloc);
|
||||||
|
|
||||||
|
child = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
_root->first_child = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
PUGI__FN xml_parse_result xml_node::append_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding)
|
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
|
// append_buffer is only valid for elements/documents
|
||||||
|
@ -576,10 +576,16 @@ namespace pugi
|
|||||||
bool remove_attribute(const xml_attribute& a);
|
bool remove_attribute(const xml_attribute& a);
|
||||||
bool remove_attribute(const char_t* name);
|
bool remove_attribute(const char_t* name);
|
||||||
|
|
||||||
|
// Remove all attributes
|
||||||
|
bool remove_attributes();
|
||||||
|
|
||||||
// Remove specified child
|
// Remove specified child
|
||||||
bool remove_child(const xml_node& n);
|
bool remove_child(const xml_node& n);
|
||||||
bool remove_child(const char_t* name);
|
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.
|
// 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.
|
// 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.
|
// Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory.
|
||||||
|
@ -492,6 +492,19 @@ TEST_XML(dom_node_remove_attribute, "<node a1='v1' a2='v2' a3='v3'><child a4='v4
|
|||||||
CHECK_NODE(doc, STR("<node a2=\"v2\"><child/></node>"));
|
CHECK_NODE(doc, STR("<node a2=\"v2\"><child/></node>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_XML(dom_node_remove_attributes, "<node a1='v1' a2='v2' a3='v3'><child a4='v4'/></node>")
|
||||||
|
{
|
||||||
|
CHECK(!xml_node().remove_attributes());
|
||||||
|
xml_node node = doc.child(STR("node"));
|
||||||
|
xml_node child = node.child(STR("child"));
|
||||||
|
|
||||||
|
CHECK(child.remove_attributes());
|
||||||
|
CHECK_NODE(child, STR("<child/>"));
|
||||||
|
|
||||||
|
CHECK(node.remove_attributes());
|
||||||
|
CHECK_NODE(node, STR("<node><child/></node>"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_XML(dom_node_prepend_child, "<node>foo<child/></node>")
|
TEST_XML(dom_node_prepend_child, "<node>foo<child/></node>")
|
||||||
{
|
{
|
||||||
CHECK(xml_node().prepend_child() == xml_node());
|
CHECK(xml_node().prepend_child() == xml_node());
|
||||||
@ -707,6 +720,19 @@ TEST_XML(dom_node_remove_child, "<node><n1/><n2/><n3/><child><n4/></child></node
|
|||||||
CHECK_NODE(doc, STR("<node><n2/><child/></node>"));
|
CHECK_NODE(doc, STR("<node><n2/><child/></node>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_XML(dom_node_remove_children, "<node><n1/><n2/><n3/><child><n4/></child></node>")
|
||||||
|
{
|
||||||
|
CHECK(!xml_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("<child/>"));
|
||||||
|
|
||||||
|
CHECK(node.remove_children());
|
||||||
|
CHECK_NODE(node, STR("<node/>"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_XML(dom_node_remove_child_complex, "<node id='1'><n1 id1='1' id2='2'/><n2/><n3/><child><n4/></child></node>")
|
TEST_XML(dom_node_remove_child_complex, "<node id='1'><n1 id1='1' id2='2'/><n2/><n3/><child><n4/></child></node>")
|
||||||
{
|
{
|
||||||
CHECK(doc.child(STR("node")).remove_child(STR("n1")));
|
CHECK(doc.child(STR("node")).remove_child(STR("n1")));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user