| /* |
| * 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 <axiom_xpath.h> |
| #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; |
| } |