[libxml++] Element::remove_attribute(): Delete the C++ wrapper



commit c75f521cefe1d6ded3e6d67397ecbbdde2ce3b48
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Wed Jul 6 16:14:52 2016 +0200

    Element::remove_attribute(): Delete the C++ wrapper
    
    * libxml++/nodes/element.cc: Call Node::free_wrappers() before the call to
    xmlUnsetProp() or xmlUnsetNsProp(). Bug #768404.
    Based on a patch by Harald Schmalzl <h schmalzl gekko at>

 libxml++/nodes/element.cc |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)
---
diff --git a/libxml++/nodes/element.cc b/libxml++/nodes/element.cc
index d3d3dd8..979b1db 100644
--- a/libxml++/nodes/element.cc
+++ b/libxml++/nodes/element.cc
@@ -133,13 +133,35 @@ Attribute* Element::set_attribute(const Glib::ustring& name, const Glib::ustring
 
 void Element::remove_attribute(const Glib::ustring& name, const Glib::ustring& ns_prefix)
 {
+  // xmlHasProp() seaches for an attribute with a specified name in any namespace.
+  // Not useful here.
+  // xmlHasNsProp() seaches both for an attribute node in the element node
+  // and for an attribute declaration in the DTD.
+  // xmlUnsetProp() or xmlUnsetNsProp() won't delete an attribute declaration.
+  auto attr = xmlHasNsProp(cobj(), (const xmlChar*)name.c_str(),
+    ns_prefix.empty() ? nullptr : (const xmlChar*)ns_prefix.c_str());
+  if (!attr || attr->type == XML_ATTRIBUTE_DECL)
+    return;
+
   if (ns_prefix.empty())
+  {
+    // *this has an attribute with the specified name and no namespace.
+    // xmlUnsetProp() will delete the existing attribute.
+    // Delete the C++ wrapper before the call to xmlUnsetProp().
+    Node::free_wrappers(reinterpret_cast<xmlNode*>(attr));
     xmlUnsetProp(cobj(), (const xmlChar*)name.c_str());
+  }
   else
   {
     auto ns = xmlSearchNs(cobj()->doc, cobj(), (const xmlChar*)ns_prefix.c_str());
     if (ns)
+    {
+      // *this has an attribute with the specified name and namespace.
+      // xmlUnsetNsProp() will delete the existing attribute.
+      // Delete the C++ wrapper before the call to xmlUnsetNsProp().
+      Node::free_wrappers(reinterpret_cast<xmlNode*>(attr));
       xmlUnsetNsProp(cobj(), ns, (const xmlChar*)name.c_str());
+    }
   }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]