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