comparison libpurple/xmlnode.c @ 32038: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
comparison
equal deleted inserted replaced
32037:114a98da1a5f 32038:8d3b5853b017
260 } 260 }
261 261
262 262
263 void xmlnode_set_namespace(xmlnode *node, const char *xmlns) 263 void xmlnode_set_namespace(xmlnode *node, const char *xmlns)
264 { 264 {
265 char *tmp;
265 g_return_if_fail(node != NULL); 266 g_return_if_fail(node != NULL);
266 267
267 g_free(node->xmlns); 268 tmp = node->xmlns;
268 node->xmlns = g_strdup(xmlns); 269 node->xmlns = g_strdup(xmlns);
270
271 if (node->namespace_map) {
272 g_hash_table_insert(node->namespace_map,
273 g_strdup(""), g_strdup(xmlns));
274 }
275
276 g_free(tmp);
269 } 277 }
270 278
271 const char *xmlnode_get_namespace(const xmlnode *node) 279 const char *xmlnode_get_namespace(const xmlnode *node)
272 { 280 {
273 g_return_val_if_fail(node != NULL, NULL); 281 g_return_val_if_fail(node != NULL, NULL);
275 return node->xmlns; 283 return node->xmlns;
276 } 284 }
277 285
278 const char *xmlnode_get_default_namespace(const xmlnode *node) 286 const char *xmlnode_get_default_namespace(const xmlnode *node)
279 { 287 {
288 const xmlnode *current_node;
280 const char *ns = NULL; 289 const char *ns = NULL;
290
281 g_return_val_if_fail(node != NULL, NULL); 291 g_return_val_if_fail(node != NULL, NULL);
282 292
283 /* If this node does *not* have a prefix, node->xmlns is the default 293 current_node = node;
284 * namespace. Otherwise, it's the prefix namespace. 294 while (current_node) {
285 */ 295 /* If this node does *not* have a prefix, node->xmlns is the default
286 if (!node->prefix && node->xmlns) { 296 * namespace. Otherwise, it's the prefix namespace.
287 return node->xmlns; 297 */
288 } else if (node->namespace_map) { 298 if (!current_node->prefix && current_node->xmlns) {
289 ns = g_hash_table_lookup(node->namespace_map, ""); 299 return current_node->xmlns;
290 } 300 } else if (current_node->namespace_map) {
291 301 ns = g_hash_table_lookup(current_node->namespace_map, "");
292 /* No default ns found? Walk up the tree looking for one */ 302 if (ns && *ns)
293 if (!(ns && *ns) && node->parent) 303 return ns;
294 ns = xmlnode_get_default_namespace(node->parent); 304 }
305
306 current_node = current_node->parent;
307 }
295 308
296 return ns; 309 return ns;
297 } 310 }
298 311
299 void xmlnode_set_prefix(xmlnode *node, const char *prefix) 312 void xmlnode_set_prefix(xmlnode *node, const char *prefix)
306 319
307 const char *xmlnode_get_prefix(const xmlnode *node) 320 const char *xmlnode_get_prefix(const xmlnode *node)
308 { 321 {
309 g_return_val_if_fail(node != NULL, NULL); 322 g_return_val_if_fail(node != NULL, NULL);
310 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 }
311 } 371 }
312 372
313 xmlnode *xmlnode_get_parent(const xmlnode *child) 373 xmlnode *xmlnode_get_parent(const xmlnode *child)
314 { 374 {
315 g_return_val_if_fail(child != NULL, NULL); 375 g_return_val_if_fail(child != NULL, NULL);