comparison libpurple/xmlnode.c @ 32819:2c6510167895 default tip

propagate from branch 'im.pidgin.pidgin.2.x.y' (head 3315c5dfbd0ad16511bdcf865e5b07c02d07df24) to branch 'im.pidgin.pidgin' (head cbd1eda6bcbf0565ae7766396bb8f6f419cb6a9a)
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sat, 02 Jun 2012 02:30:49 +0000
parents 8d3b5853b017
children
comparison
equal deleted inserted replaced
32818:01ff09d4a463 32819:2c6510167895
76 g_return_val_if_fail(name != NULL && *name != '\0', NULL); 76 g_return_val_if_fail(name != NULL && *name != '\0', NULL);
77 77
78 node = new_node(name, XMLNODE_TYPE_TAG); 78 node = new_node(name, XMLNODE_TYPE_TAG);
79 79
80 xmlnode_insert_child(parent, node); 80 xmlnode_insert_child(parent, node);
81 #if 0
82 /* This would give xmlnodes more appropriate namespacing
83 * when creating them. Otherwise, unless an explicit namespace
84 * is set, xmlnode_get_namespace() will return NULL, when
85 * there may be a default namespace.
86 *
87 * I'm unconvinced that it's useful, and concerned it may break things.
88 *
89 * _insert_child would need the same thing, probably (assuming
90 * xmlns->node == NULL)
91 */
92 xmlnode_set_namespace(node, xmlnode_get_default_namespace(node))
93 #endif
81 94
82 return node; 95 return node;
83 } 96 }
84 97
85 void 98 void
189 xmlnode_remove_attrib(node, attr); 202 xmlnode_remove_attrib(node, attr);
190 xmlnode_set_attrib_full(node, attr, NULL, NULL, value); 203 xmlnode_set_attrib_full(node, attr, NULL, NULL, value);
191 } 204 }
192 205
193 void 206 void
194 xmlnode_set_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns, const char *value)
195 {
196 xmlnode_set_attrib_full(node, attr, xmlns, NULL, value);
197 }
198
199 void
200 xmlnode_set_attrib_with_prefix(xmlnode *node, const char *attr, const char *prefix, const char *value)
201 {
202 xmlnode_set_attrib_full(node, attr, NULL, prefix, value);
203 }
204
205 void
206 xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns, const char *prefix, const char *value) 207 xmlnode_set_attrib_full(xmlnode *node, const char *attr, const char *xmlns, const char *prefix, const char *value)
207 { 208 {
208 xmlnode *attrib_node; 209 xmlnode *attrib_node;
209 210
210 g_return_if_fail(node != NULL); 211 g_return_if_fail(node != NULL);
259 } 260 }
260 261
261 262
262 void xmlnode_set_namespace(xmlnode *node, const char *xmlns) 263 void xmlnode_set_namespace(xmlnode *node, const char *xmlns)
263 { 264 {
265 char *tmp;
264 g_return_if_fail(node != NULL); 266 g_return_if_fail(node != NULL);
265 267
266 g_free(node->xmlns); 268 tmp = node->xmlns;
267 node->xmlns = g_strdup(xmlns); 269 node->xmlns = g_strdup(xmlns);
268 } 270
269 271 if (node->namespace_map) {
270 const char *xmlnode_get_namespace(xmlnode *node) 272 g_hash_table_insert(node->namespace_map,
273 g_strdup(""), g_strdup(xmlns));
274 }
275
276 g_free(tmp);
277 }
278
279 const char *xmlnode_get_namespace(const xmlnode *node)
271 { 280 {
272 g_return_val_if_fail(node != NULL, NULL); 281 g_return_val_if_fail(node != NULL, NULL);
273 282
274 return node->xmlns; 283 return node->xmlns;
284 }
285
286 const char *xmlnode_get_default_namespace(const xmlnode *node)
287 {
288 const xmlnode *current_node;
289 const char *ns = NULL;
290
291 g_return_val_if_fail(node != NULL, NULL);
292
293 current_node = node;
294 while (current_node) {
295 /* If this node does *not* have a prefix, node->xmlns is the default
296 * namespace. Otherwise, it's the prefix namespace.
297 */
298 if (!current_node->prefix && current_node->xmlns) {
299 return current_node->xmlns;
300 } else if (current_node->namespace_map) {
301 ns = g_hash_table_lookup(current_node->namespace_map, "");
302 if (ns && *ns)
303 return ns;
304 }
305
306 current_node = current_node->parent;
307 }
308
309 return ns;
275 } 310 }
276 311
277 void xmlnode_set_prefix(xmlnode *node, const char *prefix) 312 void xmlnode_set_prefix(xmlnode *node, const char *prefix)
278 { 313 {
279 g_return_if_fail(node != NULL); 314 g_return_if_fail(node != NULL);
284 319
285 const char *xmlnode_get_prefix(const xmlnode *node) 320 const char *xmlnode_get_prefix(const xmlnode *node)
286 { 321 {
287 g_return_val_if_fail(node != NULL, NULL); 322 g_return_val_if_fail(node != NULL, NULL);
288 return node->prefix; 323 return node->prefix;
324 }
325
326 const char *xmlnode_get_prefix_namespace(const xmlnode *node, const char *prefix)
327 {
328 const xmlnode *current_node;
329
330 g_return_val_if_fail(node != NULL, NULL);
331 g_return_val_if_fail(prefix != NULL, xmlnode_get_default_namespace(node));
332
333 current_node = node;
334 while (current_node) {
335 if (current_node->prefix && g_str_equal(prefix, current_node->prefix) &&
336 current_node->xmlns) {
337 return current_node->xmlns;
338 } else if (current_node->namespace_map) {
339 const char *ns = g_hash_table_lookup(current_node->namespace_map, prefix);
340 if (ns && *ns) {
341 return ns;
342 }
343 }
344
345 current_node = current_node->parent;
346 }
347
348 return NULL;
349 }
350
351 void xmlnode_strip_prefixes(xmlnode *node)
352 {
353 xmlnode *child;
354 const char *prefix;
355
356 g_return_if_fail(node != NULL);
357
358 for (child = node->child; child; child = child->next) {
359 if (child->type == XMLNODE_TYPE_TAG)
360 xmlnode_strip_prefixes(child);
361 }
362
363 prefix = xmlnode_get_prefix(node);
364 if (prefix) {
365 const char *ns = xmlnode_get_prefix_namespace(node, prefix);
366 xmlnode_set_namespace(node, ns);
367 xmlnode_set_prefix(node, NULL);
368 } else {
369 xmlnode_set_namespace(node, xmlnode_get_default_namespace(node));
370 }
289 } 371 }
290 372
291 xmlnode *xmlnode_get_parent(const xmlnode *child) 373 xmlnode *xmlnode_get_parent(const xmlnode *child)
292 { 374 {
293 g_return_val_if_fail(child != NULL, NULL); 375 g_return_val_if_fail(child != NULL, NULL);
453 } 535 }
454 536
455 if (node->namespace_map) { 537 if (node->namespace_map) {
456 g_hash_table_foreach(node->namespace_map, 538 g_hash_table_foreach(node->namespace_map,
457 (GHFunc)xmlnode_to_str_foreach_append_ns, text); 539 (GHFunc)xmlnode_to_str_foreach_append_ns, text);
458 } else if (node->xmlns) { 540 } else {
459 if(!node->parent || !purple_strequal(node->xmlns, node->parent->xmlns)) 541 /* Figure out if this node has a different default namespace from parent */
542 const char *xmlns = NULL;
543 const char *parent_xmlns = NULL;
544 if (!prefix)
545 xmlns = node->xmlns;
546
547 if (!xmlns)
548 xmlns = xmlnode_get_default_namespace(node);
549 if (node->parent)
550 parent_xmlns = xmlnode_get_default_namespace(node->parent);
551 if (!purple_strequal(xmlns, parent_xmlns))
460 { 552 {
461 char *xmlns = g_markup_escape_text(node->xmlns, -1); 553 char *escaped_xmlns = g_markup_escape_text(xmlns, -1);
462 g_string_append_printf(text, " xmlns='%s'", xmlns); 554 g_string_append_printf(text, " xmlns='%s'", escaped_xmlns);
463 g_free(xmlns); 555 g_free(escaped_xmlns);
464 } 556 }
465 } 557 }
466 for(c = node->child; c; c = c->next) 558 for(c = node->child; c; c = c->next)
467 { 559 {
468 if(c->type == XMLNODE_TYPE_ATTRIB) { 560 if(c->type == XMLNODE_TYPE_ATTRIB) {