This is an automated email from the ASF dual-hosted git repository. billblough pushed a commit to branch axiomfix in repository https://gitbox.apache.org/repos/asf/axis-axis2-c-core.git
commit e3aa37e6c6619db804de26b7c9a20b25e78faacc Author: Sanjaya Ratnaweera <[email protected]> AuthorDate: Thu Feb 21 14:15:49 2008 +0000 Commiting bill's patch in jira issue 675 --- axiom/include/axiom_node.h | 3 +- axiom/src/om/om_child_element_iterator.c | 6 +- axiom/src/om/om_children_iterator.c | 8 +- axiom/src/om/om_children_qname_iterator.c | 9 +- .../om_children_with_specific_attribute_iterator.c | 16 +- axiom/src/om/om_element.c | 70 +++--- axiom/src/om/om_node.c | 246 +++++++++++++++++++-- axiom/src/om/om_output.c | 13 +- axiom/src/soap/soap_body.c | 6 - axiom/src/soap/soap_builder.c | 6 +- 10 files changed, 289 insertions(+), 94 deletions(-) diff --git a/axiom/include/axiom_node.h b/axiom/include/axiom_node.h index e322f18..35f9f86 100644 --- a/axiom/include/axiom_node.h +++ b/axiom/include/axiom_node.h @@ -103,7 +103,8 @@ extern "C" /** * Frees an om node and all of its children. Please note that the attached - * data_element will also be freed along with the node. + * data_element will also be freed along with the node. If the node is + * still attached to a parent, it will be detached first, then freed. * @param om_node node to be freed. * @param env Environment. MUST NOT be NULL, . * @return satus of the op. AXIS2_SUCCESS on success else AXIS2_FAILURE diff --git a/axiom/src/om/om_child_element_iterator.c b/axiom/src/om/om_child_element_iterator.c index 55e67e7..d2ce598 100644 --- a/axiom/src/om/om_child_element_iterator.c +++ b/axiom/src/om/om_child_element_iterator.c @@ -66,8 +66,8 @@ AXIS2_EXTERN axis2_status_t AXIS2_CALL axiom_child_element_iterator_remove( axiom_child_element_iterator_t * iterator, const axutil_env_t * env) { - axiom_node_t *last_child = NULL; AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); if (!(iterator->next_called)) return AXIS2_FAILURE; @@ -78,8 +78,8 @@ AXIS2_EXTERN axis2_status_t AXIS2_CALL axiom_child_element_iterator_remove( if (!(iterator->last_child)) return AXIS2_FAILURE; - last_child = axiom_node_detach(iterator->last_child, env); - axiom_node_free_tree(last_child, env); + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; return AXIS2_SUCCESS; } diff --git a/axiom/src/om/om_children_iterator.c b/axiom/src/om/om_children_iterator.c index 9280e90..13c8e91 100644 --- a/axiom/src/om/om_children_iterator.c +++ b/axiom/src/om/om_children_iterator.c @@ -77,6 +77,7 @@ axiom_children_iterator_remove( { axiom_node_t *om_node = NULL; AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); if (!(iterator->next_called)) { @@ -98,11 +99,8 @@ axiom_children_iterator_remove( { return AXIS2_FAILURE; } - om_node = axiom_node_detach(iterator->last_child, env); - if (om_node) - { - axiom_node_free_tree(om_node, env); - } + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; return AXIS2_SUCCESS; } diff --git a/axiom/src/om/om_children_qname_iterator.c b/axiom/src/om/om_children_qname_iterator.c index 06b7db1..8416ca9 100644 --- a/axiom/src/om/om_children_qname_iterator.c +++ b/axiom/src/om/om_children_qname_iterator.c @@ -94,8 +94,8 @@ axiom_children_qname_iterator_remove( axiom_children_qname_iterator_t * iterator, const axutil_env_t * env) { - axiom_node_t *last_child = NULL; AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); if (!(iterator->next_called)) { @@ -115,11 +115,8 @@ axiom_children_qname_iterator_remove( if (!(iterator->last_child)) return AXIS2_FAILURE; - last_child = axiom_node_detach(iterator->last_child, env); - if (last_child) - { - axiom_node_free_tree(last_child, env); - } + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; return AXIS2_SUCCESS; } diff --git a/axiom/src/om/om_children_with_specific_attribute_iterator.c b/axiom/src/om/om_children_with_specific_attribute_iterator.c index a6da7bc..a8bded7 100644 --- a/axiom/src/om/om_children_with_specific_attribute_iterator.c +++ b/axiom/src/om/om_children_with_specific_attribute_iterator.c @@ -86,8 +86,8 @@ axiom_children_with_specific_attribute_iterator_remove( axiom_children_with_specific_attribute_iterator_t * iterator, const axutil_env_t * env) { - axiom_node_t *last_child = NULL; AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, iterator, AXIS2_FAILURE); if (!(iterator->next_called)) { @@ -107,12 +107,8 @@ axiom_children_with_specific_attribute_iterator_remove( if (!(iterator->last_child)) return AXIS2_FAILURE; - last_child = axiom_node_detach(iterator->last_child, env); - if (last_child) - { - axiom_node_free_tree(last_child, env); - last_child = NULL; - } + axiom_node_free_tree(iterator->last_child, env); + iterator->last_child = NULL; return AXIS2_SUCCESS; } @@ -175,8 +171,8 @@ axiom_children_with_specific_attribute_iterator_next( axiom_children_with_specific_attribute_iterator_t * iterator, const axutil_env_t * env) { - axiom_node_t *last_child = NULL; AXIS2_ENV_CHECK(env, NULL); + AXIS2_PARAM_CHECK(env->error, iterator, NULL); iterator->next_called = AXIS2_TRUE; iterator->remove_called = AXIS2_FALSE; @@ -186,9 +182,7 @@ axiom_children_with_specific_attribute_iterator_next( if (iterator->last_child && iterator->detach && (axiom_node_get_parent(iterator->last_child, env))) { - last_child = axiom_node_detach(iterator->last_child, env); - if (last_child) - axiom_node_free_tree(last_child, env); + axiom_node_free_tree(iterator->last_child, env); } return iterator->last_child; } diff --git a/axiom/src/om/om_element.c b/axiom/src/om/om_element.c index 48d571d..85552ac 100644 --- a/axiom/src/om/om_element.c +++ b/axiom/src/om/om_element.c @@ -232,7 +232,8 @@ axiom_element_create_with_qname( /** could not find a namespace so declare namespace */ ns = axiom_namespace_create(env, temp_nsuri, temp_prefix); - if (axiom_element_declare_namespace(om_element, env, *node, ns) == + if (ns && + axiom_element_declare_namespace(om_element, env, *node, ns) == AXIS2_SUCCESS) { (element->ns) = ns; @@ -240,7 +241,10 @@ axiom_element_create_with_qname( } else { - axiom_namespace_free(ns, env); + if (ns) + { + axiom_namespace_free(ns, env); + } axiom_element_free(om_element, env); AXIS2_FREE(env->allocator, *node); return NULL; @@ -284,7 +288,7 @@ axiom_element_find_namespace( { void *ns = NULL; - if (!prefix || axutil_strcmp(prefix, "") == 0) + if (uri && (!prefix || axutil_strcmp(prefix, "") == 0)) { /** check for a default namepsace */ @@ -293,12 +297,12 @@ axiom_element_find_namespace( default_ns = axiom_element_get_default_namespace(om_element, env, element_node); - if (default_ns && NULL != uri) + if (default_ns) { axis2_char_t *default_uri = NULL; default_uri = axiom_namespace_get_uri(default_ns, env); - if (default_uri && axutil_strcmp(uri, default_uri) == 0) + if (axutil_strcmp(uri, default_uri) == 0) { return default_ns; } @@ -320,10 +324,9 @@ axiom_element_find_namespace( temp_ns = (axiom_namespace_t *) ns; temp_nsuri = axiom_namespace_get_uri(temp_ns, env); - if (temp_nsuri && (axutil_strcmp(temp_nsuri, uri) == 0)) + if (axutil_strcmp(temp_nsuri, uri) == 0) { - - /** namespace uri matches , so free hashindex and return ns*/ + /** namespace uri matches, so free hashindex and return ns*/ AXIS2_FREE(env->allocator, hashindex); return (axiom_namespace_t *) (ns); } @@ -345,9 +348,12 @@ axiom_element_find_namespace( axiom_namespace_t *found_ns = NULL; axis2_char_t *found_uri = NULL; found_ns = (axiom_namespace_t *) ns; - found_uri = axiom_namespace_get_uri(found_ns, env); - + if (uri) + { + /* if uri provided, return found ns only if uri matches */ + return (axutil_strcmp(found_uri, uri) == 0) ? found_ns : NULL; + } return found_ns; } } @@ -500,15 +506,13 @@ axiom_element_find_declared_namespace( axutil_hash_index_t *hash_index = NULL; void *ns = NULL; AXIS2_ENV_CHECK(env, NULL); - AXIS2_PARAM_CHECK(env->error, uri, NULL); if (!(om_element->namespaces)) { return NULL; } - if (!prefix || axutil_strcmp(prefix, "") == 0) + if (uri && (!prefix || axutil_strcmp(prefix, "") == 0)) { - /** prefix null iterate the namespace hash for matching uri */ for (hash_index = axutil_hash_first(om_element->namespaces, env); hash_index; hash_index = axutil_hash_next(env, hash_index)) @@ -520,8 +524,7 @@ axiom_element_find_declared_namespace( axis2_char_t *temp_nsuri = NULL; temp_ns = (axiom_namespace_t *) (ns); temp_nsuri = axiom_namespace_get_uri(temp_ns, env); - - if (temp_nsuri && axutil_strcmp(temp_nsuri, uri) == 0) + if (axutil_strcmp(temp_nsuri, uri) == 0) { AXIS2_FREE(env->allocator, hash_index); return temp_ns; @@ -543,7 +546,8 @@ axiom_element_find_declared_namespace( axis2_char_t *found_uri = NULL; found_ns = (axiom_namespace_t *) ns; found_uri = axiom_namespace_get_uri(found_ns, env); - if (found_uri && axutil_strcmp(found_uri, uri) == 0) + /* If uri provided, ensure this namespace found by prefix matches the uri */ + if (uri && axutil_strcmp(found_uri, uri) == 0) { return found_ns; } @@ -597,8 +601,8 @@ axiom_element_add_attribute( AXIS2_PARAM_CHECK(env->error, attribute, AXIS2_FAILURE); AXIS2_PARAM_CHECK(env->error, element_node, AXIS2_FAILURE); + /* ensure the attribute's namespace structure is declared */ om_namespace = axiom_attribute_get_namespace(attribute, env); - if (om_namespace) { temp_ns = axiom_element_find_namespace(om_element, env, @@ -607,15 +611,16 @@ axiom_element_add_attribute( (om_namespace, env), axiom_namespace_get_prefix (om_namespace, env)); - if (!temp_ns) + if (temp_ns != om_namespace) { - axis2_status_t status = AXIS2_SUCCESS; - status = axiom_element_declare_namespace(om_element, env, - element_node, - om_namespace); - if (status == AXIS2_FAILURE) + axis2_status_t status; + /* as the attribute's namespace structure is not declared in scope, + declare it here */ + status = axiom_element_declare_namespace_assume_param_ownership(om_element, env, + om_namespace); + if (status != AXIS2_SUCCESS) { - return AXIS2_FAILURE; + return status; } } } @@ -635,8 +640,8 @@ axiom_element_add_attribute( axis2_char_t *name = axutil_qname_to_string(qname, env); axutil_hash_set(om_element->attributes, name, AXIS2_HASH_KEY_STRING, attribute); + axiom_attribute_increment_ref(attribute, env); } - axiom_attribute_increment_ref(attribute, env); return ((qname) ? AXIS2_SUCCESS : AXIS2_FAILURE); } @@ -1259,24 +1264,22 @@ axiom_element_set_text( const axis2_char_t * text, axiom_node_t * element_node) { - axiom_node_t *temp_node = NULL; + axiom_node_t *temp_node, *next_node; axiom_text_t *om_text = NULL; - axiom_node_t *node_to_free = NULL; AXIS2_ENV_CHECK(env, AXIS2_FAILURE); AXIS2_PARAM_CHECK(env->error, text, AXIS2_FAILURE); AXIS2_PARAM_CHECK(env->error, element_node, AXIS2_FAILURE); - temp_node = axiom_node_get_first_child(element_node, env); - while (temp_node) + next_node = axiom_node_get_first_child(element_node, env); + while (next_node) { + temp_node = next_node; + next_node = axiom_node_get_next_sibling(temp_node, env); if (axiom_node_get_node_type(temp_node, env) == AXIOM_TEXT) { - node_to_free = axiom_node_detach(temp_node, env); - axiom_node_free_tree(node_to_free, env); + axiom_node_free_tree(temp_node, env); } - temp_node = axiom_node_get_next_sibling(temp_node, env); } - temp_node = NULL; om_text = axiom_text_create(env, NULL, text, &temp_node); axiom_node_add_child(element_node, env, temp_node); @@ -1417,6 +1420,7 @@ axiom_element_declare_default_namespace( om_element->namespaces = axutil_hash_make(env); if (!(om_element->namespaces)) { + axiom_namespace_free(default_ns, env); return NULL; } } diff --git a/axiom/src/om/om_node.c b/axiom/src/om/om_node.c index 719be70..28d462e 100644 --- a/axiom/src/om/om_node.c +++ b/axiom/src/om/om_node.c @@ -60,6 +60,11 @@ struct axiom_node }; +static axiom_node_t * +axiom_node_detach_without_namespaces( + axiom_node_t * om_node, + const axutil_env_t * env); + AXIS2_EXTERN axiom_node_t *AXIS2_CALL axiom_node_create( const axutil_env_t * env) @@ -86,31 +91,20 @@ axiom_node_create( return node; } -/** - * This free fucntion will free an om_element and all the children contained in it - * before calling this function -*/ -AXIS2_EXTERN void AXIS2_CALL -axiom_node_free_tree( +static void +axiom_node_free_detached_subtree( axiom_node_t * om_node, const axutil_env_t * env) { - axiom_node_t *child_node = NULL; - AXIS2_ENV_CHECK(env, void); - if (!om_node) - { - return; - } - + /* Free any child nodes first */ if (om_node->first_child) { - while ((om_node->first_child)) + axiom_node_t *child_node = om_node->first_child, *next_sibling; + while (child_node) { - child_node = axiom_node_detach(om_node->first_child, env); - if (child_node) - { - axiom_node_free_tree(child_node, env); - } + next_sibling = child_node->next_sibling; + axiom_node_free_detached_subtree(child_node, env); + child_node = next_sibling; } } @@ -155,6 +149,30 @@ axiom_node_free_tree( return; } +/** + * This free function will free an om_element and all the children contained in it + * If the node is still attached to the tree, it will be detached first +*/ +AXIS2_EXTERN void AXIS2_CALL +axiom_node_free_tree( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + AXIS2_ENV_CHECK(env, void); + if (!om_node) + { + return; + } + + /* Detach this node before freeing it and its subtree. */ + axiom_node_detach_without_namespaces(om_node, env); + + /* Free this node and its subtree */ + axiom_node_free_detached_subtree(om_node, env); + + return; +} + AXIS2_EXTERN axis2_status_t AXIS2_CALL axiom_node_add_child( axiom_node_t * om_node, @@ -190,8 +208,12 @@ axiom_node_add_child( return AXIS2_SUCCESS; } -AXIS2_EXTERN axiom_node_t *AXIS2_CALL -axiom_node_detach( +/** + * Detach the node without regard to any namespace references in the node or + * its children. + */ +static axiom_node_t * +axiom_node_detach_without_namespaces( axiom_node_t * om_node, const axutil_env_t * env) { @@ -241,7 +263,187 @@ axiom_node_detach( om_node->next_sibling = NULL; om_node->builder = NULL; return om_node; +} + +/** + * Scan the parents of the node being detached, to determine which namespaces are inscope for the + * the detached node and its children. + */ +static axutil_hash_t * +axiom_node_detach_gather_parent_namespaces( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + axutil_hash_t *inscope_namespaces = NULL; + axiom_node_t *parent_node = om_node; + + while ((parent_node = parent_node->parent) && + (parent_node->node_type == AXIOM_ELEMENT)) + { + axiom_element_t *parent_element = parent_node->data_element; + axutil_hash_t *parent_namespaces = axiom_element_get_namespaces(parent_element, env); + if (parent_namespaces) + { + axutil_hash_index_t *hi; + void *val; + for (hi = axutil_hash_first(parent_namespaces, env); hi; + hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + if (val) + { + /* Check if prefix is already associated with some namespace in node being detached */ + if (!axiom_element_find_declared_namespace(om_node->data_element, env, NULL, + axiom_namespace_get_prefix((axiom_namespace_t *)val, env))) + { + axis2_char_t *key = axiom_namespace_get_prefix((axiom_namespace_t *)val, env); + if (!key) + key = ""; + /* Check if prefix already associated with some namespace in a parent node */ + if (!(inscope_namespaces && axutil_hash_get(inscope_namespaces, key, AXIS2_HASH_KEY_STRING))) + { + /* Remember this namespace as needing to be declared, if used */ + if (!inscope_namespaces) + inscope_namespaces = axutil_hash_make(env); + if (inscope_namespaces) + axutil_hash_set(inscope_namespaces, key, AXIS2_HASH_KEY_STRING, val); + } + } + } + } + } + } + + return inscope_namespaces; +} +/** + * Test if the provided namespace pointer is declared in a parent namespace + * If so, redeclare it in the element being detached + */ +static void +axiom_node_detach_extract_used_namespace( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_namespace_t *ns, + axiom_element_t * detached_elem, + axutil_hash_t *inscope_namespaces) +{ + if (ns) + { + axiom_namespace_t *parent_ns; + axis2_char_t *key = axiom_namespace_get_prefix(ns, env); + if (!key) + key = ""; + + parent_ns = axutil_hash_get(inscope_namespaces, key, AXIS2_HASH_KEY_STRING); + /* Check if namespace is a namespace declared in a parent and not also + declared at an intermediate level */ + if (parent_ns && (parent_ns == ns) && + (ns != axiom_element_find_namespace(om_node->data_element, env, om_node, + axiom_namespace_get_uri(ns, env), + axiom_namespace_get_prefix(ns, env)))) + { + /* Redeclare this parent namespace at the level of the element being detached */ + axiom_element_declare_namespace_assume_param_ownership(detached_elem, env, parent_ns); + /* Remove the namespace from the inscope parent namespaces now that it has + been redeclared. */ + axutil_hash_set(inscope_namespaces, key, AXIS2_HASH_KEY_STRING, NULL); + } + } +} + +/** + * For each child node, determine if it uses a namespace from a parent of the node being detached + * If so, re-declare that namespace in the node being detached + */ +static void +axiom_node_detach_extract_used_namespaces( + axiom_node_t * om_node, + const axutil_env_t * env, + axiom_element_t * detached_elem, + axutil_hash_t *inscope_namespaces) +{ + axiom_node_t *child_node; + + if (om_node->node_type == AXIOM_ELEMENT) + { + axutil_hash_t * attributes; + axiom_element_t *om_elem = om_node->data_element; + /* ensure the element's namespace is declared */ + axiom_node_detach_extract_used_namespace(om_node, env, + axiom_element_get_namespace(om_elem, env, om_node), + detached_elem, inscope_namespaces); + + /* for each attribute, ensure the attribute's namespace is declared */ + attributes = axiom_element_get_all_attributes(om_elem, env); + if (attributes) + { + axutil_hash_index_t *hi; + void *val; + for (hi = axutil_hash_first(attributes, env); hi; + hi = axutil_hash_next(env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + if (val) + { + axiom_node_detach_extract_used_namespace(om_node, env, + axiom_attribute_get_namespace((axiom_attribute_t *)val, env), + detached_elem, inscope_namespaces); + } + } + } + } + + /* ensure the namespaces in all the children are declared */ + child_node = om_node->first_child; + while (child_node && (axutil_hash_count(inscope_namespaces) > 0)) + { + if (child_node->node_type == AXIOM_ELEMENT) + { + axiom_node_detach_extract_used_namespaces(child_node, env, detached_elem, inscope_namespaces); + } + child_node = child_node->next_sibling; + } +} + +AXIS2_EXTERN axiom_node_t *AXIS2_CALL +axiom_node_detach( + axiom_node_t * om_node, + const axutil_env_t * env) +{ + axutil_hash_t *inscope_namespaces = NULL; + + AXIS2_ENV_CHECK(env, NULL); + if (!om_node) + { + return NULL; + } + + /* If this is an element node, determine which namespaces are available to it + from its parent nodes. */ + if ((om_node->node_type == AXIOM_ELEMENT) && + (om_node->data_element)) + { + inscope_namespaces = axiom_node_detach_gather_parent_namespaces(om_node, env); + } + + /* Detach this node from its parent. */ + om_node = axiom_node_detach_without_namespaces(om_node, env); + + /* If this is an element node, ensure that any namespaces available to it or its + children remain available after the detach. */ + if (om_node && inscope_namespaces) + { + axiom_node_detach_extract_used_namespaces(om_node, env, om_node->data_element, inscope_namespaces); + } + + if (inscope_namespaces) + { + axutil_hash_free(inscope_namespaces, env); + } + + return om_node; } /** @@ -271,7 +473,7 @@ axiom_node_set_parent( */ if (om_node->parent) { - om_node = axiom_node_detach(om_node, env); + om_node = axiom_node_detach_without_namespaces(om_node, env); } om_node->parent = parent; diff --git a/axiom/src/om/om_output.c b/axiom/src/om/om_output.c index a37458e..62ccae6 100644 --- a/axiom/src/om/om_output.c +++ b/axiom/src/om/om_output.c @@ -551,9 +551,16 @@ axiom_output_write( } else if (type == AXIOM_NAMESPACE) { - status = axiom_xml_writer_write_namespace(om_output->xml_writer, - env, - args_list[0], args_list[1]); + /* If the namespace prefix is xml, it must be the pre-defined xml + namespace. Although the XML spec allows it to be declared + explicitly, this is superfluous and not accepted by all xml + parsers. */ + if (strcmp(args_list[0], "xml") != 0) + { + status = axiom_xml_writer_write_namespace(om_output->xml_writer, + env, + args_list[0], args_list[1]); + } } else if (type == AXIOM_TEXT) { diff --git a/axiom/src/soap/soap_body.c b/axiom/src/soap/soap_body.c index c542567..754d74e 100644 --- a/axiom/src/soap/soap_body.c +++ b/axiom/src/soap/soap_body.c @@ -384,9 +384,6 @@ axiom_soap_body_convert_fault_to_soap11( (fault_value, env); if (fault_value_om_node) { - fault_value_om_node = - axiom_node_detach(fault_value_om_node, - env); fault_value_om_ele = (axiom_element_t *) axiom_node_get_data_element @@ -449,9 +446,6 @@ axiom_soap_body_convert_fault_to_soap11( (fault_text, env); if (fault_text_om_node) { - fault_text_om_node = - axiom_node_detach(fault_text_om_node, - env); fault_text_om_ele = (axiom_element_t *) axiom_node_get_data_element diff --git a/axiom/src/soap/soap_builder.c b/axiom/src/soap/soap_builder.c index b750c6d..1cae57a 100644 --- a/axiom/src/soap/soap_builder.c +++ b/axiom/src/soap/soap_builder.c @@ -474,7 +474,8 @@ axiom_soap_builder_construct_node( axiom_node_t *data_om_node = NULL; /*remove the <xop:Include> element */ - axiom_node_detach(om_element_node, env); + axiom_node_free_tree(om_element_node, + env); data_text = axiom_text_create_with_data_handler @@ -486,9 +487,6 @@ axiom_soap_builder_construct_node( axiom_stax_builder_set_lastnode (soap_builder->om_builder, env, parent); - axiom_node_free_tree(om_element_node, - env); - } if(id_decoded) AXIS2_FREE(env->allocator, id_decoded);
