/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "xpath_internals.h" #include "xpath_internals_engine.h" #include "xpath_internals_iterators.h" /* child */ int axiom_xpath_child_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes_tot = 0; int n_nodes; axiom_xpath_operation_t * node_test_op; axiom_node_t *cur = NULL; axiom_node_t *context_node = NULL; /* For streaming */ axiom_node_t *prev = NULL; AXIOM_XPATH_ITERATOR_INITIALIZE; cur = axiom_node_get_first_child(context->node, context->env); while(cur != NULL) { n_nodes = 0; context->node = cur; prev = cur; cur = axiom_node_get_next_sibling(cur, context->env); if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes = axiom_xpath_evaluate_predicate(context, op_next, op_predicate); n_nodes_tot += n_nodes; } } /* Change the context node back to what it was */ context->node = context_node; return n_nodes_tot; } /* descendant */ int axiom_xpath_descendant_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *child = NULL; axiom_node_t *context_node = NULL; axutil_stack_t *stack; AXIOM_XPATH_ITERATOR_INITIALIZE; /* Setting up the stack */ stack = axutil_stack_create(context->env); child = axiom_node_get_first_child(context->node, context->env); while(child) { axutil_stack_push(stack, context->env, child); child = axiom_node_get_first_child(child, context->env); } /* Processing nodes */ while(axutil_stack_size(stack, context->env) > 0) { child = (axiom_node_t *)axutil_stack_pop(stack, context->env); context->node = child; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } child = axiom_node_get_next_sibling(child, context->env); while(child) { axutil_stack_push(stack, context->env, child); child = axiom_node_get_first_child(child, context->env); } } context->node = context_node; axutil_stack_free(stack, context->env); return n_nodes; } /* parent */ int axiom_xpath_parent_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *parent = NULL; axiom_node_t *context_node = NULL; AXIOM_XPATH_ITERATOR_INITIALIZE; parent = axiom_node_get_parent(context->node, context->env); if(parent != NULL) { context->node = parent; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes = axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } } /* Change the context node back to what it was */ context->node = context_node; return n_nodes; } /* ancestor axis */ int axiom_xpath_ancestor_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *cur = NULL; axiom_node_t *context_node = NULL; AXIOM_XPATH_ITERATOR_INITIALIZE; cur = axiom_node_get_parent(context->node, context->env); while(cur != NULL) { context->node = cur; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } cur = axiom_node_get_parent(cur, context->env); } /* Change the context node back to what it was */ context->node = context_node; return n_nodes; } /* following-sibling axis */ int axiom_xpath_following_sibling_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *cur = NULL; axiom_node_t *context_node = NULL; AXIOM_XPATH_ITERATOR_INITIALIZE; cur = axiom_node_get_next_sibling(context->node, context->env); while(cur != NULL) { context->node = cur; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } cur = axiom_node_get_next_sibling(cur, context->env); } /* Change the context node back to what it was */ context->node = context_node; return n_nodes; } /* preceding-sibling axis */ int axiom_xpath_preceding_sibling_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *cur = NULL; axiom_node_t *context_node = NULL; AXIOM_XPATH_ITERATOR_INITIALIZE; cur = axiom_node_get_previous_sibling(context->node, context->env); while(cur != NULL) { context->node = cur; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } cur = axiom_node_get_previous_sibling(cur, context->env); } /* Change the context node back to what it was */ context->node = context_node; return n_nodes; } /* following */ int axiom_xpath_following_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *child = NULL, *parent = NULL; axiom_node_t *context_node = NULL; axutil_stack_t *stack; AXIOM_XPATH_ITERATOR_INITIALIZE; /* Setting up the stack */ stack = axutil_stack_create(context->env); axutil_stack_push(stack, context->env, context->node); parent = context->node; while(parent) { axutil_stack_push(stack, context->env, parent); while(axutil_stack_size(stack, context->env) > 0) { child = (axiom_node_t *)axutil_stack_pop(stack, context->env); child = axiom_node_get_next_sibling(child, context->env); while(child) { context->node = child; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } axutil_stack_push(stack, context->env, child); child = axiom_node_get_first_child(child, context->env); } } parent = axiom_node_get_parent(parent, context->env); } /* Change the context node back to what it was */ context->node = context_node; axutil_stack_free(stack, context->env); return n_nodes; } /* preceding */ int axiom_xpath_preceding_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *child = NULL, *parent = NULL; axiom_node_t *context_node = NULL; axutil_stack_t *stack; AXIOM_XPATH_ITERATOR_INITIALIZE; /* Setting up the stack */ stack = axutil_stack_create(context->env); parent = context->node; while(parent) { axutil_stack_push(stack, context->env, parent); while(axutil_stack_size(stack, context->env) > 0) { child = (axiom_node_t *)axutil_stack_pop(stack, context->env); child = axiom_node_get_previous_sibling(child, context->env); while(child) { context->node = child; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } axutil_stack_push(stack, context->env, child); child = axiom_node_get_last_child(child, context->env); } } parent = axiom_node_get_parent(parent, context->env); } /* Change the context node back to what it was */ context->node = context_node; axutil_stack_free(stack, context->env); return n_nodes; } /* attribute axis */ int axiom_xpath_attribute_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_types_t type; axiom_node_t *context_node = NULL; axiom_element_t *element; axutil_hash_t *ht; axutil_hash_index_t *hi; /* void *key; * axis2_ssize_t klen; */ void *attr; AXIOM_XPATH_ITERATOR_INITIALIZE; type = axiom_node_get_node_type(context_node, context->env); if(type != AXIOM_ELEMENT) { return 0; } element = axiom_node_get_data_element(context_node, context->env); context->node = NULL; ht = axiom_element_get_all_attributes(element, context->env); if(ht) { for(hi = axutil_hash_first(ht, context->env); hi; hi = axutil_hash_next(context->env, hi)) { attr = &context->attribute; axutil_hash_this(hi, NULL, NULL, attr); if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } } } context->node = context_node; context->attribute = NULL; return n_nodes; } /* namespace axis */ int axiom_xpath_namespace_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_types_t type; axiom_node_t *context_node = NULL; axiom_element_t *element; axutil_hash_t *ht; axutil_hash_index_t *hi; /* void *key; * axis2_ssize_t klen; */ void *ns; AXIOM_XPATH_ITERATOR_INITIALIZE; type = axiom_node_get_node_type(context_node, context->env); if(type != AXIOM_ELEMENT) { return 0; } element = axiom_node_get_data_element(context_node, context->env); context->node = NULL; ht = axiom_element_get_namespaces(element, context->env); if(ht) { for(hi = axutil_hash_first(ht, context->env); hi; hi = axutil_hash_next(context->env, hi)) { ns = &context->ns; axutil_hash_this(hi, NULL, NULL, ns); if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } } } context->node = context_node; context->ns = NULL; return n_nodes; } /* self axis */ int axiom_xpath_self_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *context_node = NULL; AXIOM_XPATH_ITERATOR_INITIALIZE; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } context->node = context_node; return n_nodes; } /* descendant-or-self axis */ int axiom_xpath_descendant_self_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *child = NULL; axiom_node_t *context_node = NULL; axutil_stack_t *stack; AXIOM_XPATH_ITERATOR_INITIALIZE; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } /* Setting up the stack */ stack = axutil_stack_create(context->env); child = axiom_node_get_first_child(context->node, context->env); while(child) { axutil_stack_push(stack, context->env, child); child = axiom_node_get_first_child(child, context->env); } /* Processing nodes */ while(axutil_stack_size(stack, context->env) > 0) { child = (axiom_node_t *)axutil_stack_pop(stack, context->env); context->node = child; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } child = axiom_node_get_next_sibling(child, context->env); while(child) { axutil_stack_push(stack, context->env, child); child = axiom_node_get_first_child(child, context->env); } } /* Change the context node back to what it was */ context->node = context_node; axutil_stack_free(stack, context->env); return n_nodes; } /* ancestor-or-self axis */ int axiom_xpath_ancestor_self_iterator( axiom_xpath_context_t *context, int op_node_test, int op_next, int op_predicate) { int n_nodes = 0; axiom_xpath_operation_t * node_test_op; axiom_node_t *parent = NULL; axiom_node_t *context_node = NULL; AXIOM_XPATH_ITERATOR_INITIALIZE; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } parent = axiom_node_get_parent(context->node, context->env); while(parent != NULL) { context->node = parent; if(axiom_xpath_node_test_match(context, (axiom_xpath_node_test_t *)node_test_op->par1)) { n_nodes += axiom_xpath_evaluate_predicate(context, op_next, op_predicate); } parent = axiom_node_get_parent(parent, context->env); } /* Change the context node back to what it was */ context->node = context_node; return n_nodes; }