Mercurial > pidgin.yaz
comparison libpurple/xmlnode.c @ 32692:0f94ec89f0bc
merged from im.pidgin.pidgin
| author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
|---|---|
| date | Mon, 26 Sep 2011 14:57:21 +0900 |
| parents | 9aee8493db7f 8d3b5853b017 |
| children |
comparison
equal
deleted
inserted
replaced
| 32438:55e678325bda | 32692:0f94ec89f0bc |
|---|---|
| 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) { |
