Mercurial > pidgin
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) { |