xml BUGFIX handling namespaces in parent/child elements of the same name
correctly remove active namespaces (via lyxml_ns_rm()) in case the
parent element holding the namespace definition has the same name
(stored as the same memory chunk) as its child.
diff --git a/src/xml.c b/src/xml.c
index ccc0849..8fa1c7e 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -648,7 +648,13 @@
ns = malloc(sizeof *ns);
LY_CHECK_ERR_RET(!ns, LOGMEM(context->ctx), LY_EMEM);
+ /* to distinguish 2 elements, we need not only the name, but also its depth in the XML tree.
+ * In case some dictionary is used to store elements' names (so name strings of 2 distinguish nodes
+ * actually points to the same memory), so the depth is necessary to distinguish parent/child nodes
+ * of the same name. Otherwise, the namespace defined in parent could be removed when leaving child node. */
+ ns->element_depth = context->elements.count;
ns->element = element_name;
+
ns->uri = uri;
if (prefix) {
ns->prefix = strndup(prefix, prefix_len);
@@ -688,8 +694,12 @@
unsigned int u;
for (u = context->ns.count - 1; u + 1 > 0; --u) {
- if (((struct lyxml_ns *)context->ns.objs[u])->element != element_name) {
- /* we are done, the namespaces from a single element are supposed to be together */
+ if (((struct lyxml_ns *)context->ns.objs[u])->element != element_name ||
+ ((struct lyxml_ns *)context->ns.objs[u])->element_depth != context->elements.count + 1) {
+ /* we are done, the namespaces from a single element are supposed to be together;
+ * the second condition is there to distinguish parent/child elements with the same name
+ * (which are for some reason stored at the same memory chunk), so we need to distinguish
+ * level of the node */
break;
}
/* remove the ns structure */
diff --git a/src/xml.h b/src/xml.h
index e12af7d..70431ea 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -48,6 +48,7 @@
const char *element; /* element where the namespace is defined */
char *prefix; /* prefix of the namespace, NULL for the default namespace */
char *uri; /* namespace URI */
+ unsigned int element_depth; /* depth level of the element to distinguish parent-child elements of the same name */
};
/* element tag identifier for matching opening and closing tags */