blob: 225bea6c00e963ef30cc8c51a6e2b201f94441b6 [file] [log] [blame]
/*
* 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;
}