Mercurial > pidgin.yaz
diff libpurple/xmlnode.c @ 32499:8d3b5853b017
xmlnode: Add xmlnode_strip_prefixes
This is largely based on a patch from Thijs (sphynx/xnyhps) Alkemade, with
some modifications by me to try to maintain namespaces of elements
as best as we can.
I also rewrote xmlnode_get_default_namespace not to use recursion.
References #14529
| author | Paul Aurich <paul@darkrain42.org> |
|---|---|
| date | Sun, 04 Sep 2011 21:06:26 +0000 |
| parents | 114a98da1a5f |
| children | 0f94ec89f0bc |
line wrap: on
line diff
--- a/libpurple/xmlnode.c Sun Sep 04 18:52:18 2011 +0000 +++ b/libpurple/xmlnode.c Sun Sep 04 21:06:26 2011 +0000 @@ -262,10 +262,18 @@ void xmlnode_set_namespace(xmlnode *node, const char *xmlns) { + char *tmp; g_return_if_fail(node != NULL); - g_free(node->xmlns); + tmp = node->xmlns; node->xmlns = g_strdup(xmlns); + + if (node->namespace_map) { + g_hash_table_insert(node->namespace_map, + g_strdup(""), g_strdup(xmlns)); + } + + g_free(tmp); } const char *xmlnode_get_namespace(const xmlnode *node) @@ -277,22 +285,27 @@ const char *xmlnode_get_default_namespace(const xmlnode *node) { + const xmlnode *current_node; const char *ns = NULL; + g_return_val_if_fail(node != NULL, NULL); - /* If this node does *not* have a prefix, node->xmlns is the default - * namespace. Otherwise, it's the prefix namespace. - */ - if (!node->prefix && node->xmlns) { - return node->xmlns; - } else if (node->namespace_map) { - ns = g_hash_table_lookup(node->namespace_map, ""); + current_node = node; + while (current_node) { + /* If this node does *not* have a prefix, node->xmlns is the default + * namespace. Otherwise, it's the prefix namespace. + */ + if (!current_node->prefix && current_node->xmlns) { + return current_node->xmlns; + } else if (current_node->namespace_map) { + ns = g_hash_table_lookup(current_node->namespace_map, ""); + if (ns && *ns) + return ns; + } + + current_node = current_node->parent; } - /* No default ns found? Walk up the tree looking for one */ - if (!(ns && *ns) && node->parent) - ns = xmlnode_get_default_namespace(node->parent); - return ns; } @@ -310,6 +323,53 @@ return node->prefix; } +const char *xmlnode_get_prefix_namespace(const xmlnode *node, const char *prefix) +{ + const xmlnode *current_node; + + g_return_val_if_fail(node != NULL, NULL); + g_return_val_if_fail(prefix != NULL, xmlnode_get_default_namespace(node)); + + current_node = node; + while (current_node) { + if (current_node->prefix && g_str_equal(prefix, current_node->prefix) && + current_node->xmlns) { + return current_node->xmlns; + } else if (current_node->namespace_map) { + const char *ns = g_hash_table_lookup(current_node->namespace_map, prefix); + if (ns && *ns) { + return ns; + } + } + + current_node = current_node->parent; + } + + return NULL; +} + +void xmlnode_strip_prefixes(xmlnode *node) +{ + xmlnode *child; + const char *prefix; + + g_return_if_fail(node != NULL); + + for (child = node->child; child; child = child->next) { + if (child->type == XMLNODE_TYPE_TAG) + xmlnode_strip_prefixes(child); + } + + prefix = xmlnode_get_prefix(node); + if (prefix) { + const char *ns = xmlnode_get_prefix_namespace(node, prefix); + xmlnode_set_namespace(node, ns); + xmlnode_set_prefix(node, NULL); + } else { + xmlnode_set_namespace(node, xmlnode_get_default_namespace(node)); + } +} + xmlnode *xmlnode_get_parent(const xmlnode *child) { g_return_val_if_fail(child != NULL, NULL);
