/* * 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" /* Evaluates the expath expression */ axiom_xpath_result_t * axiom_xpath_run( axiom_xpath_context_t *context) { axiom_xpath_result_t* res; /* Initialize result ret */ res = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_t)); res->flag = 0; res->nodes = axutil_array_list_create(context->env, 0); /* Expression is empty */ if(context->expr->start == AXIOM_XPATH_PARSE_END) { return res; } context->stack = axutil_stack_create(context->env); axiom_xpath_evaluate_operation(context, context->expr->start); /* Add nodes to the result set from the stack */ while(axutil_stack_size(context->stack, context->env) > 0) { axutil_array_list_add(res->nodes, context->env, axutil_stack_pop(context->stack, context->env)); } axutil_stack_free(context->stack, context->env); return res; } /* Casting functions; these make use of the casting functions defined in xpath.h */ void axiom_xpath_cast_boolean( axiom_xpath_result_node_t *node, axiom_xpath_context_t *context) { axis2_bool_t v = axiom_xpath_cast_node_to_boolean(context->env, node); AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, v); node->type = AXIOM_XPATH_TYPE_BOOLEAN; } void axiom_xpath_cast_number( axiom_xpath_result_node_t *node, axiom_xpath_context_t *context) { double v = axiom_xpath_cast_node_to_number(context->env, node); AXIOM_XPATH_CAST_SET_VALUE(double, v); node->type = AXIOM_XPATH_TYPE_NUMBER; } void axiom_xpath_cast_string( axiom_xpath_result_node_t *node, axiom_xpath_context_t *context) { node->value = axiom_xpath_cast_node_to_string(context->env, node); node->type = AXIOM_XPATH_TYPE_TEXT; } /* Evaluate whether two results are equal If either node is a boolean other is casted to a boolean; Otherwise, if either node is a number other is casted to a number; Otherwise, both nodes are casted to strings.*/ axis2_bool_t axiom_xpath_compare_equal( axiom_xpath_result_node_t *node1, axiom_xpath_result_node_t *node2, axiom_xpath_context_t *context) { if(node1->type == AXIOM_XPATH_TYPE_BOOLEAN || node2->type == AXIOM_XPATH_TYPE_BOOLEAN) { axiom_xpath_cast_boolean(node1, context); axiom_xpath_cast_boolean(node2, context); if(*(axis2_bool_t*)(node1->value) == *(axis2_bool_t*)(node2->value)) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } if(node1->type == AXIOM_XPATH_TYPE_NUMBER || node2->type == AXIOM_XPATH_TYPE_NUMBER) { axiom_xpath_cast_number(node1, context); axiom_xpath_cast_number(node2, context); if(*(double *)(node1->value) == *(double *)(node2->value)) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } axiom_xpath_cast_string(node1, context); axiom_xpath_cast_string(node2, context); if(axutil_strcmp((axis2_char_t *)(node1->value), (axis2_char_t *)(node2->value)) == 0) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } /* Convert a node set to boolean */ axis2_bool_t axiom_xpath_convert_to_boolean( axutil_array_list_t *node_set, axiom_xpath_context_t *context) { if(axutil_array_list_size(node_set, context->env) == 0) { return AXIS2_FALSE; } else if(axutil_array_list_size(node_set, context->env) >= 2) { return AXIS2_TRUE; } else { axiom_xpath_result_node_t *node = axutil_array_list_get(node_set, context->env, 0); axiom_xpath_cast_boolean(node, context); return *(axis2_bool_t *)node->value; } } /* Operators */ /* Literal */ int axiom_xpath_literal_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { axiom_xpath_result_node_t *node; node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); /* Set the context node to NULL */ /* This is not required; it gives some problems */ /* context->node = NULL;*/ node->value = op->par1; node->type = AXIOM_XPATH_TYPE_TEXT; axutil_stack_push(context->stack, context->env, node); return 1; } /* Number */ int axiom_xpath_number_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { axiom_xpath_result_node_t *node; node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); /* Set the context node to NULL */ /* This is not required; it gives some problems */ /* context->node = NULL;*/ node->value = op->par1; node->type = AXIOM_XPATH_TYPE_NUMBER; axutil_stack_push(context->stack, context->env, node); return 1; } /* Path Expression */ int axiom_xpath_path_expression_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { int filter_res_n, n_nodes = 0; axiom_xpath_operation_t *rel_loc_op; axiom_xpath_operator_t rel_loc_func; axutil_array_list_t *arr; axiom_xpath_result_node_t *res_node; int i; /* Filter operation */ if(op->op1 == AXIOM_XPATH_PARSE_END) { return 0; } filter_res_n = axiom_xpath_evaluate_operation(context, op->op1); /* Relative location path */ if(op->op2 == AXIOM_XPATH_PARSE_END) { return filter_res_n; } rel_loc_op = AXIOM_XPATH_OPR_GET(op->op2); rel_loc_func = axiom_xpath_get_operator(rel_loc_op); /* Array list to add all results from the filter expression */ arr = axutil_array_list_create(context->env, 0); for(i = 0; i < filter_res_n; i++) { axutil_array_list_add(arr, context->env, axutil_stack_pop(context->stack, context->env)); } /* Evaluate relative location path for all results from the filter expression */ for(i = 0; i < axutil_array_list_size(arr, context->env); i++) { res_node = (axiom_xpath_result_node_t *)axutil_array_list_get(arr, context->env, i); if(res_node->type == AXIOM_XPATH_TYPE_NODE) { context->node = (axiom_node_t *)res_node->value; context->position = i + 1; context->size = filter_res_n; n_nodes += rel_loc_func(context, rel_loc_op); } AXIS2_FREE(context->env->allocator, res_node); } axutil_array_list_free(arr, context->env); return n_nodes; } /* Or Expression */ int axiom_xpath_orexpr_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { axiom_xpath_result_node_t *node; axiom_xpath_result_node_t *res_node; int n_nodes[2]; int i, j; int op12[2]; axutil_array_list_t *arr[2]; op12[0] = op->op1; op12[1] = op->op2; /* Evaluate both operands and get number of results */ for(i = 0; i < 2; i++) { if(op12[i] == AXIOM_XPATH_PARSE_END) { continue; } n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]); } for(i = 1; i >= 0; i--) { arr[i] = axutil_array_list_create(context->env, 0); for(j = 0; j < n_nodes[i]; j++) { axutil_array_list_add(arr[i], context->env, axutil_stack_pop(context->stack, context->env)); } } node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); node->type = AXIOM_XPATH_TYPE_BOOLEAN; node->value = NULL; /* Checking equality - If any node from the first set is equal to any node from the second set the result is true */ if(axiom_xpath_convert_to_boolean(arr[0], context) || axiom_xpath_convert_to_boolean(arr[1], context)) { AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE); axutil_stack_push(context->stack, context->env, node); } else { AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE); axutil_stack_push(context->stack, context->env, node); } for (i = 1; i >= 0; i--) { for (j = 0; j < n_nodes[i]; j++) { res_node = (axiom_xpath_result_node_t *)axutil_array_list_get(arr[i], context->env, j); AXIS2_FREE(context->env->allocator, res_node); } axutil_array_list_free(arr[i], context->env); } return 1; } /* And Expression */ int axiom_xpath_andexpr_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { axiom_xpath_result_node_t *node; axiom_xpath_result_node_t *res_node; int n_nodes[2]; int i, j; int op12[2]; axutil_array_list_t *arr[2]; op12[0] = op->op1; op12[1] = op->op2; /* Evaluate both operands and get number of results */ for(i = 0; i < 2; i++) { if(op12[i] == AXIOM_XPATH_PARSE_END) { continue; } n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]); } for(i = 1; i >= 0; i--) { arr[i] = axutil_array_list_create(context->env, 0); for(j = 0; j < n_nodes[i]; j++) { axutil_array_list_add(arr[i], context->env, axutil_stack_pop(context->stack, context->env)); } } node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); node->type = AXIOM_XPATH_TYPE_BOOLEAN; node->value = NULL; /* Checking equality - If any node from the first set is equal to any node from the second set the result is true */ if(axiom_xpath_convert_to_boolean(arr[0], context) && axiom_xpath_convert_to_boolean(arr[1], context)) { AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE); axutil_stack_push(context->stack, context->env, node); } else { AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE); axutil_stack_push(context->stack, context->env, node); } for (i = 1; i >= 0; i--) { for (j = 0; j < n_nodes[i]; j++) { res_node = (axiom_xpath_result_node_t *)axutil_array_list_get(arr[i], context->env, j); AXIS2_FREE(context->env->allocator, res_node); } axutil_array_list_free(arr[i], context->env); } return 1; } /* Equal Expression */ int axiom_xpath_equalexpr_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { axiom_xpath_result_node_t *node; axiom_xpath_result_node_t *res_node; int n_nodes[2]; int i, j; int op12[2]; axutil_array_list_t *arr[2]; op12[0] = op->op1; op12[1] = op->op2; /* Evaluate both operands and get number of results */ for(i = 0; i < 2; i++) { if(op12[i] == AXIOM_XPATH_PARSE_END) { continue; } n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]); } for(i = 1; i >= 0; i--) { arr[i] = axutil_array_list_create(context->env, 0); for(j = 0; j < n_nodes[i]; j++) { axutil_array_list_add(arr[i], context->env, axutil_stack_pop(context->stack, context->env)); } } node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); node->type = AXIOM_XPATH_TYPE_BOOLEAN; node->value = NULL; /* Checking equality - If any node from the first set is equal to any node from the second set the result is true */ for(i = 0; i < n_nodes[0]; i++) { for(j = 0; j < n_nodes[1]; j++) { if(axiom_xpath_compare_equal(axutil_array_list_get(arr[0], context->env, i), axutil_array_list_get(arr[1], context->env, j), context)) { AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE); axutil_stack_push(context->stack, context->env, node); break; } } if(j < n_nodes[1]) { break; } } if(!node->value) { AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE); axutil_stack_push(context->stack, context->env, node); } for (i = 1; i >= 0; i--) { for (j = 0; j < n_nodes[i]; j++) { res_node =(axiom_xpath_result_node_t *)axutil_array_list_get(arr[i], context->env, j); AXIS2_FREE(context->env->allocator, res_node); } axutil_array_list_free(arr[i], context->env); } return 1; } /* Union */ int axiom_xpath_union_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { int n_nodes = 0; int i; int op12[2]; op12[0] = op->op1; op12[1] = op->op2; for(i = 0; i < 2; i++) { if(op12[i] == AXIOM_XPATH_PARSE_END) { continue; } n_nodes += axiom_xpath_evaluate_operation(context, op12[i]); } return n_nodes; } /* Set context node depending on whether relative or absolute location path */ int axiom_xpath_start_node_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { int n_nodes = 0; if(op->op1 == AXIOM_XPATH_PARSE_END) { return 0; } if(op->opr == AXIOM_XPATH_OPERATION_ROOT_NODE) { context->node = context->root_node; n_nodes += axiom_xpath_evaluate_operation(context, op->op1); } else if(op->opr == AXIOM_XPATH_OPERATION_CONTEXT_NODE) { n_nodes += axiom_xpath_evaluate_operation(context, op->op1); } return n_nodes; } /* Step */ int axiom_xpath_step_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { axiom_xpath_operation_t * node_test_op; axiom_xpath_iterator_t iter; axiom_xpath_axis_t axis; if(op->op1 == AXIOM_XPATH_PARSE_END) { #ifdef AXIOM_XPATH_DEBUG printf("Node test operator empty\n"); #endif return AXIOM_XPATH_EVALUATION_ERROR; } if(op->op2 == AXIOM_XPATH_PARSE_END) { return 0; } /* Get the name */ node_test_op = AXIOM_XPATH_OPR_GET(op->op1); /* Get the axis */ if(!node_test_op->par2) { #ifdef AXIOM_XPATH_DEBUG printf("axis is NULL in the step operator\n"); #endif return AXIOM_XPATH_EVALUATION_ERROR; } axis = *((axiom_xpath_axis_t *)node_test_op->par2); /* Get the iteration for the axis */ iter = axiom_xpath_get_iterator(axis); return iter(context, op->op1 /* node test */, op->op2 /* next step */, node_test_op->op1 /* predicate */); } /* Predicates */ axis2_bool_t axiom_xpath_evaluate_predicate_condition( axiom_xpath_context_t *context, int n_nodes) { axiom_xpath_result_node_t *res; int i; if(n_nodes <= 0) { return AXIS2_FALSE; } else if(n_nodes > 1) { for(i = 0; i < n_nodes; i++) { res = (axiom_xpath_result_node_t *)axutil_stack_pop(context->stack, context->env); if (res->type > AXIOM_XPATH_TYPE_NAMESPACE) { AXIS2_FREE(context->env->allocator, res->value); } AXIS2_FREE(context->env->allocator, res); } return AXIS2_TRUE; } else { res = (axiom_xpath_result_node_t *)axutil_stack_pop(context->stack, context->env); if(res->type == AXIOM_XPATH_TYPE_NUMBER) { if(*(double *)(res->value) == context->position) { AXIS2_FREE(context->env->allocator, res); return AXIS2_TRUE; } else { AXIS2_FREE(context->env->allocator, res); return AXIS2_FALSE; } } else if(res->type == AXIOM_XPATH_TYPE_BOOLEAN) { if(*(axis2_bool_t *)(res->value)) { AXIS2_FREE(context->env->allocator, res); return AXIS2_TRUE; } else { AXIS2_FREE(context->env->allocator, res); return AXIS2_FALSE; } } else { AXIS2_FREE(context->env->allocator, res); return AXIS2_TRUE; } } } /* Predicate */ int axiom_xpath_evaluate_predicate( axiom_xpath_context_t *context, int op_next, int op_predicate) { int n_res; axis2_bool_t res; axiom_xpath_operation_t * pred_op; axiom_node_t *context_node = context->node; if(op_predicate == AXIOM_XPATH_PARSE_END) { return axiom_xpath_evaluate_operation(context, op_next); } else { pred_op = AXIOM_XPATH_OPR_GET(op_predicate); pred_op->pos++; /* Evaluate the predicate */ if(pred_op->op1 != AXIOM_XPATH_PARSE_END) { n_res = axiom_xpath_evaluate_operation(context, pred_op->op1); context->position = pred_op->pos; res = axiom_xpath_evaluate_predicate_condition(context, n_res); } else { res = AXIS2_TRUE; } /* A PredicateExpr is evaluated by evaluating the Expr and converting the result to a boolean. If the result is a number, the result will be converted to true if the number is equal to the context position and will be converted to false otherwise; if the result is not a number, then the result will be converted as if by a call to the boolean function. */ /* Transform the result to number or boolean ? */ if(res) { context->node = context_node; return axiom_xpath_evaluate_predicate(context, op_next, pred_op->op2); } } return 0; } /* Node test match */ axis2_bool_t axiom_xpath_node_test_match( axiom_xpath_context_t *context, axiom_xpath_node_test_t *node_test) { axiom_types_t type; axiom_element_t *element = NULL; axis2_char_t *name = NULL; axiom_namespace_t *ns = NULL, *xpath_ns = NULL; if(!context->node && !context->attribute && !context->ns) { #ifdef AXIOM_XPATH_DEBUG printf("Both context node and attribute are NULL."); printf(" May be a literal or a number.\n"); #endif return AXIS2_FALSE; } else if(context->node) { /* Test if the node matches */ type = axiom_node_get_node_type(context->node, context->env); if(type == AXIOM_ELEMENT) { element = axiom_node_get_data_element(context->node, context->env); name = axiom_element_get_localname(element, context->env); ns = axiom_element_get_namespace(element, context->env, context->node); } if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE) { return AXIS2_FALSE; } else { if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL || node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD) { if(type != AXIOM_ELEMENT) { return AXIS2_FALSE; } /* Check namespace */ if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) { if(!ns && node_test->prefix) { return AXIS2_FALSE; } } else { if((ns && !node_test->prefix) || (!ns && node_test->prefix)) { return AXIS2_FALSE; } } if(ns && node_test->prefix) { xpath_ns = axiom_xpath_get_namespace(context, node_test->prefix); if(!xpath_ns) { return AXIS2_FALSE; } if(axutil_strcmp(axiom_namespace_get_uri(ns, context->env), axiom_namespace_get_uri(xpath_ns, context->env))) { return AXIS2_FALSE; } } /* Check local name */ if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) { return AXIS2_TRUE; } else if(node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD) { if(name && axutil_strcmp(node_test->name, name) == 0) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } } else if(node_test->type == AXIOM_XPATH_NODE_TYPE_COMMENT) { if(type == AXIOM_COMMENT) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } else if(node_test->type == AXIOM_XPATH_NODE_TYPE_PI) { if(type == AXIOM_PROCESSING_INSTRUCTION) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } else if(node_test->type == AXIOM_XPATH_NODE_TYPE_NODE) { if(type == AXIOM_ELEMENT) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } else if(node_test->type == AXIOM_XPATH_NODE_TYPE_TEXT) { if(type == AXIOM_TEXT) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } } } /* Attributes */ else if(context->attribute) { name = axiom_attribute_get_localname(context->attribute, context->env); ns = axiom_attribute_get_namespace(context->attribute, context->env); if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE) { return AXIS2_FALSE; } else { /* Check namespace */ if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) { if(!ns && node_test->prefix) { return AXIS2_FALSE; } } else { if((ns && !node_test->prefix) || (!ns && node_test->prefix)) { return AXIS2_FALSE; } } if(ns && node_test->prefix) { xpath_ns = axiom_xpath_get_namespace(context, node_test->prefix); if(!xpath_ns) { return AXIS2_FALSE; } if(axutil_strcmp(axiom_namespace_get_uri(ns, context->env), axiom_namespace_get_uri(xpath_ns, context->env))) { return AXIS2_FALSE; } } /* Check local name */ if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) { return AXIS2_TRUE; } else if(node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD) { if(name && axutil_strcmp(node_test->name, name) == 0) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } } } /* Namespace */ else if(context->ns) { /* Prefix is checked ??? If changed to uri the cast method in xpath.c needs to be changed as well */ name = axiom_namespace_get_prefix(context->ns, context->env); ns = NULL; if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE) { return AXIS2_FALSE; } else { /* Check namespace */ if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) { if(!ns && node_test->prefix) { return AXIS2_FALSE; } } else { if((ns && !node_test->prefix) || (!ns && node_test->prefix)) { return AXIS2_FALSE; } } if(ns && node_test->prefix) { xpath_ns = axiom_xpath_get_namespace(context, node_test->prefix); if(!xpath_ns) { return AXIS2_FALSE; } if(axutil_strcmp(axiom_namespace_get_uri(ns, context->env), axiom_namespace_get_uri(xpath_ns, context->env))) { return AXIS2_FALSE; } } /* Check local name */ if(node_test->type == AXIOM_XPATH_NODE_TEST_ALL) { return AXIS2_TRUE; } else if(node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD) { if(name && axutil_strcmp(node_test->name, name) == 0) { return AXIS2_TRUE; } else { return AXIS2_FALSE; } } } } return AXIS2_FALSE; } int axiom_xpath_function_call_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { axiom_xpath_function_t func = axiom_xpath_get_function(context, op->par1); int n_args = 0; if(!func) { #ifdef AXIOM_XPATH_DEBUG printf("Function %s not found\n", (char *)op->par1); #endif return AXIOM_XPATH_EVALUATION_ERROR; } if(op->op1 != AXIOM_XPATH_PARSE_END) { n_args = axiom_xpath_evaluate_operation(context, op->op1); } return func(context, n_args); } int axiom_xpath_argument_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { int n_args = 0; if(op->op1 != AXIOM_XPATH_PARSE_END) { n_args += axiom_xpath_evaluate_operation(context, op->op1); } if(op->op2 != AXIOM_XPATH_PARSE_END) { n_args += axiom_xpath_evaluate_operation(context, op->op1); } return n_args; } /* Collect the current node to the results list */ int axiom_xpath_collect_operator( axiom_xpath_context_t *context, axiom_xpath_operation_t * op) { axiom_xpath_result_node_t *node; node = AXIS2_MALLOC(context->env->allocator, sizeof(axiom_xpath_result_node_t)); if(context->node) { node->value = context->node; node->type = AXIOM_XPATH_TYPE_NODE; } else if(context->attribute) { node->value = context->attribute; node->type = AXIOM_XPATH_TYPE_ATTRIBUTE; } else if(context->ns) { node->value = context->ns; node->type = AXIOM_XPATH_TYPE_NAMESPACE; } axutil_stack_push(context->stack, context->env, node); return 1; } /* Returns a pointer to the respective processing function */ axiom_xpath_operator_t axiom_xpath_get_operator( axiom_xpath_operation_t * op) { switch(op->opr) { case AXIOM_XPATH_OPERATION_STEP: return axiom_xpath_step_operator; case AXIOM_XPATH_OPERATION_ROOT_NODE: case AXIOM_XPATH_OPERATION_CONTEXT_NODE: return axiom_xpath_start_node_operator; case AXIOM_XPATH_OPERATION_RESULT: return axiom_xpath_collect_operator; case AXIOM_XPATH_OPERATION_UNION: return axiom_xpath_union_operator; case AXIOM_XPATH_OPERATION_OR_EXPR: return axiom_xpath_orexpr_operator; case AXIOM_XPATH_OPERATION_AND_EXPR: return axiom_xpath_andexpr_operator; case AXIOM_XPATH_OPERATION_EQUAL_EXPR: return axiom_xpath_equalexpr_operator; case AXIOM_XPATH_OPERATION_LITERAL: return axiom_xpath_literal_operator; case AXIOM_XPATH_OPERATION_NUMBER: return axiom_xpath_number_operator; case AXIOM_XPATH_OPERATION_PATH_EXPRESSION: return axiom_xpath_path_expression_operator; case AXIOM_XPATH_OPERATION_FUNCTION_CALL: return axiom_xpath_function_call_operator; case AXIOM_XPATH_OPERATION_ARGUMENT: return axiom_xpath_argument_operator; default: #ifdef AXIOM_XPATH_DEBUG printf("Unidentified operation.\n"); #endif return NULL; } } /* Returns a pointer to the respective processing function */ axiom_xpath_iterator_t axiom_xpath_get_iterator( axiom_xpath_axis_t axis) { switch(axis) { case AXIOM_XPATH_AXIS_CHILD: return axiom_xpath_child_iterator; case AXIOM_XPATH_AXIS_DESCENDANT: return axiom_xpath_descendant_iterator; case AXIOM_XPATH_AXIS_PARENT: return axiom_xpath_parent_iterator; case AXIOM_XPATH_AXIS_ANCESTOR: return axiom_xpath_ancestor_iterator; case AXIOM_XPATH_AXIS_FOLLOWING_SIBLING: return axiom_xpath_following_sibling_iterator; case AXIOM_XPATH_AXIS_PRECEDING_SIBLING: return axiom_xpath_preceding_sibling_iterator; case AXIOM_XPATH_AXIS_FOLLOWING: return axiom_xpath_following_iterator; case AXIOM_XPATH_AXIS_PRECEDING: return axiom_xpath_preceding_iterator; case AXIOM_XPATH_AXIS_ATTRIBUTE: return axiom_xpath_attribute_iterator; case AXIOM_XPATH_AXIS_NAMESPACE: return axiom_xpath_namespace_iterator; case AXIOM_XPATH_AXIS_SELF: return axiom_xpath_self_iterator; case AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF: return axiom_xpath_descendant_self_iterator; case AXIOM_XPATH_AXIS_ANCESTOR_OR_SELF: return axiom_xpath_ancestor_self_iterator; default: #ifdef AXIOM_XPATH_DEBUG printf("Unidentified axis.\n"); #endif return NULL; } } int axiom_xpath_evaluate_operation( axiom_xpath_context_t *context, int op) { axiom_xpath_operation_t * operation; axiom_xpath_operator_t function; /* Get a pointer to the operation */ operation = AXIOM_XPATH_OPR_GET(op); /* Get the funciton which processes the operations */ function = axiom_xpath_get_operator(operation); return function(context, operation); }