Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes
xpath_ast_node Class Reference
Collaboration diagram for xpath_ast_node:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 xpath_ast_node (ast_type_t type, xpath_value_type rettype_, const char_t *value)
 xpath_ast_node (ast_type_t type, xpath_value_type rettype_, double value)
 xpath_ast_node (ast_type_t type, xpath_value_type rettype_, xpath_variable *value)
 xpath_ast_node (ast_type_t type, xpath_value_type rettype_, xpath_ast_node *left=0, xpath_ast_node *right=0)
 xpath_ast_node (ast_type_t type, xpath_ast_node *left, axis_t axis, nodetest_t test, const char_t *contents)
void set_next (xpath_ast_node *value)
void set_right (xpath_ast_node *value)
bool eval_boolean (const xpath_context &c, const xpath_stack &stack)
double eval_number (const xpath_context &c, const xpath_stack &stack)
xpath_string eval_string_concat (const xpath_context &c, const xpath_stack &stack)
xpath_string eval_string (const xpath_context &c, const xpath_stack &stack)
xpath_node_set_raw eval_node_set (const xpath_context &c, const xpath_stack &stack)
bool is_posinv ()
xpath_value_type rettype () const

Private Member Functions

 xpath_ast_node (const xpath_ast_node &)
xpath_ast_nodeoperator= (const xpath_ast_node &)
void apply_predicate (xpath_node_set_raw &ns, size_t first, xpath_ast_node *expr, const xpath_stack &stack)
void apply_predicates (xpath_node_set_raw &ns, size_t first, const xpath_stack &stack)
void step_push (xpath_node_set_raw &ns, const xml_attribute &a, const xml_node &parent, xpath_allocator *alloc)
void step_push (xpath_node_set_raw &ns, const xml_node &n, xpath_allocator *alloc)
template<class T >
void step_fill (xpath_node_set_raw &ns, const xml_node &n, xpath_allocator *alloc, T)
template<class T >
void step_fill (xpath_node_set_raw &ns, const xml_attribute &a, const xml_node &p, xpath_allocator *alloc, T v)
template<class T >
xpath_node_set_raw step_do (const xpath_context &c, const xpath_stack &stack, T v)

Static Private Member Functions

template<class Comp >
static bool compare_eq (xpath_ast_node *lhs, xpath_ast_node *rhs, const xpath_context &c, const xpath_stack &stack, const Comp &comp)
template<class Comp >
static bool compare_rel (xpath_ast_node *lhs, xpath_ast_node *rhs, const xpath_context &c, const xpath_stack &stack, const Comp &comp)

Private Attributes

char _type
char _rettype
char _axis
char _test
xpath_ast_node_left
xpath_ast_node_right
xpath_ast_node_next
union {
   const char_t *   string
   double   number
   xpath_variable *   variable
   const char_t *   nodetest
_data

Detailed Description

Definition at line 7918 of file pugixml.cpp.


Constructor & Destructor Documentation

xpath_ast_node::xpath_ast_node ( ast_type_t  type,
xpath_value_type  rettype_,
const char_t *  value 
) [inline]

Definition at line 8519 of file pugixml.cpp.

References _data, and ast_string_constant.

                                                                                               :
                        _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0)
                {
                        assert(type == ast_string_constant);
                        _data.string = value;
                }
xpath_ast_node::xpath_ast_node ( ast_type_t  type,
xpath_value_type  rettype_,
double  value 
) [inline]

Definition at line 8526 of file pugixml.cpp.

References _data, and ast_number_constant.

                                                                                        :
                        _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0)
                {
                        assert(type == ast_number_constant);
                        _data.number = value;
                }
xpath_ast_node::xpath_ast_node ( ast_type_t  type,
xpath_value_type  rettype_,
xpath_variable *  value 
) [inline]

Definition at line 8533 of file pugixml.cpp.

References _data, and ast_variable.

                                                                                                 :
                        _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0)
                {
                        assert(type == ast_variable);
                        _data.variable = value;
                }
xpath_ast_node::xpath_ast_node ( ast_type_t  type,
xpath_value_type  rettype_,
xpath_ast_node left = 0,
xpath_ast_node right = 0 
) [inline]

Definition at line 8540 of file pugixml.cpp.

                                                                                                                               :
                        _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(left), _right(right), _next(0)
                {
                }
xpath_ast_node::xpath_ast_node ( ast_type_t  type,
xpath_ast_node left,
axis_t  axis,
nodetest_t  test,
const char_t *  contents 
) [inline]

Definition at line 8545 of file pugixml.cpp.

References _data.

                                                                                                                           :
                        _type(static_cast<char>(type)), _rettype(xpath_type_node_set), _axis(static_cast<char>(axis)), _test(static_cast<char>(test)), _left(left), _right(0), _next(0)
                {
                        _data.nodetest = contents;
                }

Member Function Documentation

void xpath_ast_node::apply_predicate ( xpath_node_set_raw ns,
size_t  first,
xpath_ast_node expr,
const xpath_stack stack 
) [inline, private]

Definition at line 8108 of file pugixml.cpp.

References xpath_node_set_raw::begin(), xpath_node_set_raw::end(), eval_boolean(), eval_number(), rettype(), xpath_node_set_raw::size(), and xpath_node_set_raw::truncate().

Referenced by apply_predicates(), and eval_node_set().

                {
                        assert(ns.size() >= first);

                        size_t i = 1;
                        size_t size = ns.size() - first;
                                
                        xpath_node* last = ns.begin() + first;
                                
                        // remove_if... or well, sort of
                        for (xpath_node* it = last; it != ns.end(); ++it, ++i)
                        {
                                xpath_context c(*it, i, size);
                        
                                if (expr->rettype() == xpath_type_number)
                                {
                                        if (expr->eval_number(c, stack) == i)
                                                *last++ = *it;
                                }
                                else if (expr->eval_boolean(c, stack))
                                        *last++ = *it;
                        }
                        
                        ns.truncate(last);
                }
void xpath_ast_node::apply_predicates ( xpath_node_set_raw ns,
size_t  first,
const xpath_stack stack 
) [inline, private]

Definition at line 8134 of file pugixml.cpp.

References _next, _right, apply_predicate(), and xpath_node_set_raw::size().

Referenced by step_do().

                {
                        if (ns.size() == first) return;
                        
                        for (xpath_ast_node* pred = _right; pred; pred = pred->_next)
                        {
                                apply_predicate(ns, first, pred->_left, stack);
                        }
                }
template<class Comp >
static bool xpath_ast_node::compare_eq ( xpath_ast_node lhs,
xpath_ast_node rhs,
const xpath_context c,
const xpath_stack stack,
const Comp &  comp 
) [inline, static, private]

Definition at line 7949 of file pugixml.cpp.

References xpath_node_set_raw::begin(), xpath_string::c_str(), convert_string_to_number(), xpath_node_set_raw::end(), eval_boolean(), eval_node_set(), eval_number(), eval_string(), xpath_stack::result, rettype(), string_value(), and swap().

Referenced by eval_boolean().

                {
                        xpath_value_type lt = lhs->rettype(), rt = rhs->rettype();

                        if (lt != xpath_type_node_set && rt != xpath_type_node_set)
                        {
                                if (lt == xpath_type_boolean || rt == xpath_type_boolean)
                                        return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack));
                                else if (lt == xpath_type_number || rt == xpath_type_number)
                                        return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack));
                                else if (lt == xpath_type_string || rt == xpath_type_string)
                                {
                                        xpath_allocator_capture cr(stack.result);

                                        xpath_string ls = lhs->eval_string(c, stack);
                                        xpath_string rs = rhs->eval_string(c, stack);

                                        return comp(ls, rs);
                                }
                        }
                        else if (lt == xpath_type_node_set && rt == xpath_type_node_set)
                        {
                                xpath_allocator_capture cr(stack.result);

                                xpath_node_set_raw ls = lhs->eval_node_set(c, stack);
                                xpath_node_set_raw rs = rhs->eval_node_set(c, stack);

                                for (const xpath_node* li = ls.begin(); li != ls.end(); ++li)
                                        for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
                                        {
                                                xpath_allocator_capture cri(stack.result);

                                                if (comp(string_value(*li, stack.result), string_value(*ri, stack.result)))
                                                        return true;
                                        }

                                return false;
                        }
                        else
                        {
                                if (lt == xpath_type_node_set)
                                {
                                        swap(lhs, rhs);
                                        swap(lt, rt);
                                }

                                if (lt == xpath_type_boolean)
                                        return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack));
                                else if (lt == xpath_type_number)
                                {
                                        xpath_allocator_capture cr(stack.result);

                                        double l = lhs->eval_number(c, stack);
                                        xpath_node_set_raw rs = rhs->eval_node_set(c, stack);

                                        for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
                                        {
                                                xpath_allocator_capture cri(stack.result);

                                                if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str())))
                                                        return true;
                                        }

                                        return false;
                                }
                                else if (lt == xpath_type_string)
                                {
                                        xpath_allocator_capture cr(stack.result);

                                        xpath_string l = lhs->eval_string(c, stack);
                                        xpath_node_set_raw rs = rhs->eval_node_set(c, stack);

                                        for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
                                        {
                                                xpath_allocator_capture cri(stack.result);

                                                if (comp(l, string_value(*ri, stack.result)))
                                                        return true;
                                        }

                                        return false;
                                }
                        }

                        assert(!"Wrong types");
                        return false;
                }
template<class Comp >
static bool xpath_ast_node::compare_rel ( xpath_ast_node lhs,
xpath_ast_node rhs,
const xpath_context c,
const xpath_stack stack,
const Comp &  comp 
) [inline, static, private]

Definition at line 8037 of file pugixml.cpp.

References xpath_node_set_raw::begin(), xpath_string::c_str(), convert_string_to_number(), xpath_node_set_raw::end(), eval_node_set(), eval_number(), xpath_stack::result, rettype(), and string_value().

Referenced by eval_boolean().

                {
                        xpath_value_type lt = lhs->rettype(), rt = rhs->rettype();

                        if (lt != xpath_type_node_set && rt != xpath_type_node_set)
                                return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack));
                        else if (lt == xpath_type_node_set && rt == xpath_type_node_set)
                        {
                                xpath_allocator_capture cr(stack.result);

                                xpath_node_set_raw ls = lhs->eval_node_set(c, stack);
                                xpath_node_set_raw rs = rhs->eval_node_set(c, stack);

                                for (const xpath_node* li = ls.begin(); li != ls.end(); ++li)
                                {
                                        xpath_allocator_capture cri(stack.result);

                                        double l = convert_string_to_number(string_value(*li, stack.result).c_str());

                                        for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
                                        {
                                                xpath_allocator_capture crii(stack.result);

                                                if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str())))
                                                        return true;
                                        }
                                }

                                return false;
                        }
                        else if (lt != xpath_type_node_set && rt == xpath_type_node_set)
                        {
                                xpath_allocator_capture cr(stack.result);

                                double l = lhs->eval_number(c, stack);
                                xpath_node_set_raw rs = rhs->eval_node_set(c, stack);

                                for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
                                {
                                        xpath_allocator_capture cri(stack.result);

                                        if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str())))
                                                return true;
                                }

                                return false;
                        }
                        else if (lt == xpath_type_node_set && rt != xpath_type_node_set)
                        {
                                xpath_allocator_capture cr(stack.result);

                                xpath_node_set_raw ls = lhs->eval_node_set(c, stack);
                                double r = rhs->eval_number(c, stack);

                                for (const xpath_node* li = ls.begin(); li != ls.end(); ++li)
                                {
                                        xpath_allocator_capture cri(stack.result);

                                        if (comp(convert_string_to_number(string_value(*li, stack.result).c_str()), r))
                                                return true;
                                }

                                return false;
                        }
                        else
                        {
                                assert(!"Wrong types");
                                return false;
                        }
                }
bool xpath_ast_node::eval_boolean ( const xpath_context c,
const xpath_stack stack 
) [inline]

Definition at line 8561 of file pugixml.cpp.

References _data, _left, _rettype, _right, _type, ast_func_boolean, ast_func_contains, ast_func_false, ast_func_lang, ast_func_not, ast_func_starts_with, ast_func_true, ast_op_and, ast_op_equal, ast_op_greater, ast_op_greater_or_equal, ast_op_less, ast_op_less_or_equal, ast_op_not_equal, ast_op_or, ast_variable, xpath_string::c_str(), compare_eq(), compare_rel(), convert_number_to_boolean(), xpath_string::empty(), xpath_node_set_raw::empty(), eval_boolean(), eval_node_set(), eval_number(), eval_string(), find_substring(), xpath_context::n, xpath_stack::result, starts_with(), and tolower_ascii().

Referenced by apply_predicate(), compare_eq(), eval_boolean(), eval_number(), and eval_string().

                {
                        switch (_type)
                        {
                        case ast_op_or:
                                return _left->eval_boolean(c, stack) || _right->eval_boolean(c, stack);
                                
                        case ast_op_and:
                                return _left->eval_boolean(c, stack) && _right->eval_boolean(c, stack);
                                
                        case ast_op_equal:
                                return compare_eq(_left, _right, c, stack, equal_to());

                        case ast_op_not_equal:
                                return compare_eq(_left, _right, c, stack, not_equal_to());
        
                        case ast_op_less:
                                return compare_rel(_left, _right, c, stack, less());
                        
                        case ast_op_greater:
                                return compare_rel(_right, _left, c, stack, less());

                        case ast_op_less_or_equal:
                                return compare_rel(_left, _right, c, stack, less_equal());
                        
                        case ast_op_greater_or_equal:
                                return compare_rel(_right, _left, c, stack, less_equal());

                        case ast_func_starts_with:
                        {
                                xpath_allocator_capture cr(stack.result);

                                xpath_string lr = _left->eval_string(c, stack);
                                xpath_string rr = _right->eval_string(c, stack);

                                return starts_with(lr.c_str(), rr.c_str());
                        }

                        case ast_func_contains:
                        {
                                xpath_allocator_capture cr(stack.result);

                                xpath_string lr = _left->eval_string(c, stack);
                                xpath_string rr = _right->eval_string(c, stack);

                                return find_substring(lr.c_str(), rr.c_str()) != 0;
                        }

                        case ast_func_boolean:
                                return _left->eval_boolean(c, stack);
                                
                        case ast_func_not:
                                return !_left->eval_boolean(c, stack);
                                
                        case ast_func_true:
                                return true;
                                
                        case ast_func_false:
                                return false;

                        case ast_func_lang:
                        {
                                if (c.n.attribute()) return false;
                                
                                xpath_allocator_capture cr(stack.result);

                                xpath_string lang = _left->eval_string(c, stack);
                                
                                for (xml_node n = c.n.node(); n; n = n.parent())
                                {
                                        xml_attribute a = n.attribute(PUGIXML_TEXT("xml:lang"));
                                        
                                        if (a)
                                        {
                                                const char_t* value = a.value();
                                                
                                                // strnicmp / strncasecmp is not portable
                                                for (const char_t* lit = lang.c_str(); *lit; ++lit)
                                                {
                                                        if (tolower_ascii(*lit) != tolower_ascii(*value)) return false;
                                                        ++value;
                                                }
                                                
                                                return *value == 0 || *value == '-';
                                        }
                                }
                                
                                return false;
                        }

                        case ast_variable:
                        {
                                assert(_rettype == _data.variable->type());

                                if (_rettype == xpath_type_boolean)
                                        return _data.variable->get_boolean();

                                // fallthrough to type conversion
                        }

                        default:
                        {
                                switch (_rettype)
                                {
                                case xpath_type_number:
                                        return convert_number_to_boolean(eval_number(c, stack));
                                        
                                case xpath_type_string:
                                {
                                        xpath_allocator_capture cr(stack.result);

                                        return !eval_string(c, stack).empty();
                                }
                                        
                                case xpath_type_node_set:                               
                                {
                                        xpath_allocator_capture cr(stack.result);

                                        return !eval_node_set(c, stack).empty();
                                }

                                default:
                                        assert(!"Wrong expression for return type boolean");
                                        return false;
                                }
                        }
                        }
                }
xpath_node_set_raw xpath_ast_node::eval_node_set ( const xpath_context c,
const xpath_stack stack 
) [inline]

Definition at line 9094 of file pugixml.cpp.

References _axis, _data, _left, _rettype, _right, _type, xpath_node_set_raw::append(), apply_predicate(), ast_filter, ast_filter_posinv, ast_func_id, ast_op_union, ast_step, ast_step_root, ast_variable, axis_ancestor, axis_ancestor_or_self, axis_attribute, axis_child, axis_descendant, axis_descendant_or_self, axis_following, axis_following_sibling, axis_namespace, axis_parent, axis_preceding, axis_preceding_sibling, axis_self, xpath_node_set_raw::begin(), xpath_node_set_raw::end(), eval_node_set(), xpath_context::n, xpath_node_set_raw::push_back(), xpath_node_set_raw::remove_duplicates(), xpath_stack::result, xpath_node_set_raw::set_type(), xpath_node_set_raw::sort_do(), step_do(), and xpath_stack::temp.

Referenced by compare_eq(), compare_rel(), eval_boolean(), eval_node_set(), eval_number(), eval_string(), and step_do().

                {
                        switch (_type)
                        {
                        case ast_op_union:
                        {
                                xpath_allocator_capture cr(stack.temp);

                                xpath_stack swapped_stack = {stack.temp, stack.result};

                                xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack);
                                xpath_node_set_raw rs = _right->eval_node_set(c, stack);
                                
                                // we can optimize merging two sorted sets, but this is a very rare operation, so don't bother
                                rs.set_type(xpath_node_set::type_unsorted);

                                rs.append(ls.begin(), ls.end(), stack.result);
                                rs.remove_duplicates();
                                
                                return rs;
                        }

                        case ast_filter:
                        case ast_filter_posinv:
                        {
                                xpath_node_set_raw set = _left->eval_node_set(c, stack);

                                // either expression is a number or it contains position() call; sort by document order
                                if (_type == ast_filter) set.sort_do();

                                apply_predicate(set, 0, _right, stack);
                        
                                return set;
                        }
                        
                        case ast_func_id:
                                return xpath_node_set_raw();
                        
                        case ast_step:
                        {
                                switch (_axis)
                                {
                                case axis_ancestor:
                                        return step_do(c, stack, axis_to_type<axis_ancestor>());
                                        
                                case axis_ancestor_or_self:
                                        return step_do(c, stack, axis_to_type<axis_ancestor_or_self>());

                                case axis_attribute:
                                        return step_do(c, stack, axis_to_type<axis_attribute>());

                                case axis_child:
                                        return step_do(c, stack, axis_to_type<axis_child>());
                                
                                case axis_descendant:
                                        return step_do(c, stack, axis_to_type<axis_descendant>());

                                case axis_descendant_or_self:
                                        return step_do(c, stack, axis_to_type<axis_descendant_or_self>());

                                case axis_following:
                                        return step_do(c, stack, axis_to_type<axis_following>());
                                
                                case axis_following_sibling:
                                        return step_do(c, stack, axis_to_type<axis_following_sibling>());
                                
                                case axis_namespace:
                                        // namespaced axis is not supported
                                        return xpath_node_set_raw();
                                
                                case axis_parent:
                                        return step_do(c, stack, axis_to_type<axis_parent>());
                                
                                case axis_preceding:
                                        return step_do(c, stack, axis_to_type<axis_preceding>());

                                case axis_preceding_sibling:
                                        return step_do(c, stack, axis_to_type<axis_preceding_sibling>());
                                
                                case axis_self:
                                        return step_do(c, stack, axis_to_type<axis_self>());

                                default:
                                        assert(!"Unknown axis");
                                        return xpath_node_set_raw();
                                }
                        }

                        case ast_step_root:
                        {
                                assert(!_right); // root step can't have any predicates

                                xpath_node_set_raw ns;

                                ns.set_type(xpath_node_set::type_sorted);

                                if (c.n.node()) ns.push_back(c.n.node().root(), stack.result);
                                else if (c.n.attribute()) ns.push_back(c.n.parent().root(), stack.result);

                                return ns;
                        }

                        case ast_variable:
                        {
                                assert(_rettype == _data.variable->type());

                                if (_rettype == xpath_type_node_set)
                                {
                                        const xpath_node_set& s = _data.variable->get_node_set();

                                        xpath_node_set_raw ns;

                                        ns.set_type(s.type());
                                        ns.append(s.begin(), s.end(), stack.result);

                                        return ns;
                                }

                                // fallthrough to type conversion
                        }

                        default:
                                assert(!"Wrong expression for return type node set");
                                return xpath_node_set_raw();
                        }
                }
double xpath_ast_node::eval_number ( const xpath_context c,
const xpath_stack stack 
) [inline]

Definition at line 8690 of file pugixml.cpp.

References _data, _left, _rettype, _right, _type, ast_func_ceiling, ast_func_count, ast_func_floor, ast_func_last, ast_func_number_0, ast_func_number_1, ast_func_position, ast_func_round, ast_func_string_length_0, ast_func_string_length_1, ast_func_sum, ast_number_constant, ast_op_add, ast_op_divide, ast_op_mod, ast_op_multiply, ast_op_negate, ast_op_subtract, ast_variable, xpath_node_set_raw::begin(), xpath_string::c_str(), convert_string_to_number(), xpath_node_set_raw::end(), eval_boolean(), eval_node_set(), eval_number(), eval_string(), xpath_string::length(), xpath_context::n, xpath_context::position, xpath_stack::result, round_nearest_nzero(), xpath_node_set_raw::size(), xpath_context::size, and string_value().

Referenced by apply_predicate(), compare_eq(), compare_rel(), eval_boolean(), eval_number(), and eval_string().

                {
                        switch (_type)
                        {
                        case ast_op_add:
                                return _left->eval_number(c, stack) + _right->eval_number(c, stack);
                                
                        case ast_op_subtract:
                                return _left->eval_number(c, stack) - _right->eval_number(c, stack);

                        case ast_op_multiply:
                                return _left->eval_number(c, stack) * _right->eval_number(c, stack);

                        case ast_op_divide:
                                return _left->eval_number(c, stack) / _right->eval_number(c, stack);

                        case ast_op_mod:
                                return fmod(_left->eval_number(c, stack), _right->eval_number(c, stack));

                        case ast_op_negate:
                                return -_left->eval_number(c, stack);

                        case ast_number_constant:
                                return _data.number;

                        case ast_func_last:
                                return static_cast<double>(c.size);
                        
                        case ast_func_position:
                                return static_cast<double>(c.position);

                        case ast_func_count:
                        {
                                xpath_allocator_capture cr(stack.result);

                                return static_cast<double>(_left->eval_node_set(c, stack).size());
                        }
                        
                        case ast_func_string_length_0:
                        {
                                xpath_allocator_capture cr(stack.result);

                                return static_cast<double>(string_value(c.n, stack.result).length());
                        }
                        
                        case ast_func_string_length_1:
                        {
                                xpath_allocator_capture cr(stack.result);

                                return static_cast<double>(_left->eval_string(c, stack).length());
                        }
                        
                        case ast_func_number_0:
                        {
                                xpath_allocator_capture cr(stack.result);

                                return convert_string_to_number(string_value(c.n, stack.result).c_str());
                        }
                        
                        case ast_func_number_1:
                                return _left->eval_number(c, stack);

                        case ast_func_sum:
                        {
                                xpath_allocator_capture cr(stack.result);

                                double r = 0;
                                
                                xpath_node_set_raw ns = _left->eval_node_set(c, stack);
                                
                                for (const xpath_node* it = ns.begin(); it != ns.end(); ++it)
                                {
                                        xpath_allocator_capture cri(stack.result);

                                        r += convert_string_to_number(string_value(*it, stack.result).c_str());
                                }
                        
                                return r;
                        }

                        case ast_func_floor:
                        {
                                double r = _left->eval_number(c, stack);
                                
                                return r == r ? floor(r) : r;
                        }

                        case ast_func_ceiling:
                        {
                                double r = _left->eval_number(c, stack);
                                
                                return r == r ? ceil(r) : r;
                        }

                        case ast_func_round:
                                return round_nearest_nzero(_left->eval_number(c, stack));
                        
                        case ast_variable:
                        {
                                assert(_rettype == _data.variable->type());

                                if (_rettype == xpath_type_number)
                                        return _data.variable->get_number();

                                // fallthrough to type conversion
                        }

                        default:
                        {
                                switch (_rettype)
                                {
                                case xpath_type_boolean:
                                        return eval_boolean(c, stack) ? 1 : 0;
                                        
                                case xpath_type_string:
                                {
                                        xpath_allocator_capture cr(stack.result);

                                        return convert_string_to_number(eval_string(c, stack).c_str());
                                }
                                        
                                case xpath_type_node_set:
                                {
                                        xpath_allocator_capture cr(stack.result);

                                        return convert_string_to_number(eval_string(c, stack).c_str());
                                }
                                        
                                default:
                                        assert(!"Wrong expression for return type number");
                                        return 0;
                                }
                                
                        }
                        }
                }
xpath_string xpath_ast_node::eval_string ( const xpath_context c,
const xpath_stack stack 
) [inline]

Definition at line 8876 of file pugixml.cpp.

References _data, _left, _next, _rettype, _right, _type, ast_func_concat, ast_func_local_name_0, ast_func_local_name_1, ast_func_name_0, ast_func_name_1, ast_func_namespace_uri_0, ast_func_namespace_uri_1, ast_func_normalize_space_0, ast_func_normalize_space_1, ast_func_string_0, ast_func_string_1, ast_func_substring_2, ast_func_substring_3, ast_func_substring_after, ast_func_substring_before, ast_func_translate, ast_string_constant, ast_variable, xpath_string::c_str(), convert_number_to_string(), xpath_string::data(), xpath_node_set_raw::empty(), eval_boolean(), eval_node_set(), eval_number(), eval_string(), eval_string_concat(), find_substring(), xpath_node_set_raw::first(), is_nan(), xpath_string::length(), local_name(), xpath_context::n, namespace_uri(), normalize_space(), qualified_name(), xpath_stack::result, round_nearest(), string_value(), xpath_stack::temp, translate(), xpath_string::uses_heap(), and xpath_string_const().

Referenced by compare_eq(), eval_boolean(), eval_number(), eval_string(), eval_string_concat(), and evaluate_string_impl().

                {
                        switch (_type)
                        {
                        case ast_string_constant:
                                return xpath_string_const(_data.string);
                        
                        case ast_func_local_name_0:
                        {
                                xpath_node na = c.n;
                                
                                return xpath_string_const(local_name(na));
                        }

                        case ast_func_local_name_1:
                        {
                                xpath_allocator_capture cr(stack.result);

                                xpath_node_set_raw ns = _left->eval_node_set(c, stack);
                                xpath_node na = ns.first();
                                
                                return xpath_string_const(local_name(na));
                        }

                        case ast_func_name_0:
                        {
                                xpath_node na = c.n;
                                
                                return xpath_string_const(qualified_name(na));
                        }

                        case ast_func_name_1:
                        {
                                xpath_allocator_capture cr(stack.result);

                                xpath_node_set_raw ns = _left->eval_node_set(c, stack);
                                xpath_node na = ns.first();
                                
                                return xpath_string_const(qualified_name(na));
                        }

                        case ast_func_namespace_uri_0:
                        {
                                xpath_node na = c.n;
                                
                                return xpath_string_const(namespace_uri(na));
                        }

                        case ast_func_namespace_uri_1:
                        {
                                xpath_allocator_capture cr(stack.result);

                                xpath_node_set_raw ns = _left->eval_node_set(c, stack);
                                xpath_node na = ns.first();
                                
                                return xpath_string_const(namespace_uri(na));
                        }

                        case ast_func_string_0:
                                return string_value(c.n, stack.result);

                        case ast_func_string_1:
                                return _left->eval_string(c, stack);

                        case ast_func_concat:
                                return eval_string_concat(c, stack);

                        case ast_func_substring_before:
                        {
                                xpath_allocator_capture cr(stack.temp);

                                xpath_stack swapped_stack = {stack.temp, stack.result};

                                xpath_string s = _left->eval_string(c, swapped_stack);
                                xpath_string p = _right->eval_string(c, swapped_stack);

                                const char_t* pos = find_substring(s.c_str(), p.c_str());
                                
                                return pos ? xpath_string(s.c_str(), pos, stack.result) : xpath_string();
                        }
                        
                        case ast_func_substring_after:
                        {
                                xpath_allocator_capture cr(stack.temp);

                                xpath_stack swapped_stack = {stack.temp, stack.result};

                                xpath_string s = _left->eval_string(c, swapped_stack);
                                xpath_string p = _right->eval_string(c, swapped_stack);
                                
                                const char_t* pos = find_substring(s.c_str(), p.c_str());
                                if (!pos) return xpath_string();

                                const char_t* result = pos + p.length();

                                return s.uses_heap() ? xpath_string(result, stack.result) : xpath_string_const(result);
                        }

                        case ast_func_substring_2:
                        {
                                xpath_allocator_capture cr(stack.temp);

                                xpath_stack swapped_stack = {stack.temp, stack.result};

                                xpath_string s = _left->eval_string(c, swapped_stack);
                                size_t s_length = s.length();

                                double first = round_nearest(_right->eval_number(c, stack));
                                
                                if (is_nan(first)) return xpath_string(); // NaN
                                else if (first >= s_length + 1) return xpath_string();
                                
                                size_t pos = first < 1 ? 1 : static_cast<size_t>(first);
                                assert(1 <= pos && pos <= s_length + 1);

                                const char_t* rbegin = s.c_str() + (pos - 1);
                                
                                return s.uses_heap() ? xpath_string(rbegin, stack.result) : xpath_string_const(rbegin);
                        }
                        
                        case ast_func_substring_3:
                        {
                                xpath_allocator_capture cr(stack.temp);

                                xpath_stack swapped_stack = {stack.temp, stack.result};

                                xpath_string s = _left->eval_string(c, swapped_stack);
                                size_t s_length = s.length();

                                double first = round_nearest(_right->eval_number(c, stack));
                                double last = first + round_nearest(_right->_next->eval_number(c, stack));
                                
                                if (is_nan(first) || is_nan(last)) return xpath_string();
                                else if (first >= s_length + 1) return xpath_string();
                                else if (first >= last) return xpath_string();
                                else if (last < 1) return xpath_string();
                                
                                size_t pos = first < 1 ? 1 : static_cast<size_t>(first);
                                size_t end = last >= s_length + 1 ? s_length + 1 : static_cast<size_t>(last);

                                assert(1 <= pos && pos <= end && end <= s_length + 1);
                                const char_t* rbegin = s.c_str() + (pos - 1);
                                const char_t* rend = s.c_str() + (end - 1);

                                return (end == s_length + 1 && !s.uses_heap()) ? xpath_string_const(rbegin) : xpath_string(rbegin, rend, stack.result);
                        }

                        case ast_func_normalize_space_0:
                        {
                                xpath_string s = string_value(c.n, stack.result);

                                normalize_space(s.data(stack.result));

                                return s;
                        }

                        case ast_func_normalize_space_1:
                        {
                                xpath_string s = _left->eval_string(c, stack);

                                normalize_space(s.data(stack.result));
                        
                                return s;
                        }

                        case ast_func_translate:
                        {
                                xpath_allocator_capture cr(stack.temp);

                                xpath_stack swapped_stack = {stack.temp, stack.result};

                                xpath_string s = _left->eval_string(c, stack);
                                xpath_string from = _right->eval_string(c, swapped_stack);
                                xpath_string to = _right->_next->eval_string(c, swapped_stack);

                                translate(s.data(stack.result), from.c_str(), to.c_str());

                                return s;
                        }

                        case ast_variable:
                        {
                                assert(_rettype == _data.variable->type());

                                if (_rettype == xpath_type_string)
                                        return xpath_string_const(_data.variable->get_string());

                                // fallthrough to type conversion
                        }

                        default:
                        {
                                switch (_rettype)
                                {
                                case xpath_type_boolean:
                                        return xpath_string_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"));
                                        
                                case xpath_type_number:
                                        return convert_number_to_string(eval_number(c, stack), stack.result);
                                        
                                case xpath_type_node_set:
                                {
                                        xpath_allocator_capture cr(stack.temp);

                                        xpath_stack swapped_stack = {stack.temp, stack.result};

                                        xpath_node_set_raw ns = eval_node_set(c, swapped_stack);
                                        return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result);
                                }
                                
                                default:
                                        assert(!"Wrong expression for return type string");
                                        return xpath_string();
                                }
                        }
                        }
                }
xpath_string xpath_ast_node::eval_string_concat ( const xpath_context c,
const xpath_stack stack 
) [inline]

Definition at line 8827 of file pugixml.cpp.

References _left, _next, _right, _type, xpath_allocator::allocate(), ast_func_concat, eval_string(), xpath_stack::result, and xpath_stack::temp.

Referenced by eval_string().

                {
                        assert(_type == ast_func_concat);

                        xpath_allocator_capture ct(stack.temp);

                        // count the string number
                        size_t count = 1;
                        for (xpath_ast_node* nc = _right; nc; nc = nc->_next) count++;

                        // gather all strings
                        xpath_string static_buffer[4];
                        xpath_string* buffer = static_buffer;

                        // allocate on-heap for large concats
                        if (count > sizeof(static_buffer) / sizeof(static_buffer[0]))
                        {
                                buffer = static_cast<xpath_string*>(stack.temp->allocate(count * sizeof(xpath_string)));
                                assert(buffer);
                        }

                        // evaluate all strings to temporary stack
                        xpath_stack swapped_stack = {stack.temp, stack.result};

                        buffer[0] = _left->eval_string(c, swapped_stack);

                        size_t pos = 1;
                        for (xpath_ast_node* n = _right; n; n = n->_next, ++pos) buffer[pos] = n->eval_string(c, swapped_stack);
                        assert(pos == count);

                        // get total length
                        size_t length = 0;
                        for (size_t i = 0; i < count; ++i) length += buffer[i].length();

                        // create final string
                        char_t* result = static_cast<char_t*>(stack.result->allocate((length + 1) * sizeof(char_t)));
                        assert(result);

                        char_t* ri = result;

                        for (size_t j = 0; j < count; ++j)
                                for (const char_t* bi = buffer[j].c_str(); *bi; ++bi)
                                        *ri++ = *bi;

                        *ri = 0;

                        return xpath_string(result, true);
                }
bool xpath_ast_node::is_posinv ( ) [inline]

Definition at line 9221 of file pugixml.cpp.

References _left, _next, _right, _type, ast_filter, ast_filter_posinv, ast_func_position, ast_number_constant, ast_predicate, ast_step, ast_step_root, ast_string_constant, ast_variable, and is_posinv().

Referenced by is_posinv(), and xpath_parser::parse_filter_expression().

                {
                        switch (_type)
                        {
                        case ast_func_position:
                                return false;

                        case ast_string_constant:
                        case ast_number_constant:
                        case ast_variable:
                                return true;

                        case ast_step:
                        case ast_step_root:
                                return true;

                        case ast_predicate:
                        case ast_filter:
                        case ast_filter_posinv:
                                return true;

                        default:
                                if (_left && !_left->is_posinv()) return false;
                                
                                for (xpath_ast_node* n = _right; n; n = n->_next)
                                        if (!n->is_posinv()) return false;
                                        
                                return true;
                        }
                }
xpath_ast_node& xpath_ast_node::operator= ( const xpath_ast_node ) [private]
xpath_value_type xpath_ast_node::rettype ( ) const [inline]
void xpath_ast_node::set_next ( xpath_ast_node value) [inline]

Definition at line 8551 of file pugixml.cpp.

References _next.

Referenced by xpath_parser::parse_primary_expression(), and xpath_parser::parse_step().

                {
                        _next = value;
                }
void xpath_ast_node::set_right ( xpath_ast_node value) [inline]

Definition at line 8556 of file pugixml.cpp.

References _right.

Referenced by xpath_parser::parse_step().

                {
                        _right = value;
                }
template<class T >
xpath_node_set_raw xpath_ast_node::step_do ( const xpath_context c,
const xpath_stack stack,
v 
) [inline, private]

Definition at line 8470 of file pugixml.cpp.

References _left, apply_predicates(), axis_ancestor, axis_ancestor_or_self, axis_attribute, axis_child, axis_descendant_or_self, axis_following, axis_parent, axis_preceding, axis_preceding_sibling, axis_self, xpath_node_set_raw::begin(), xpath_node_set_raw::end(), eval_node_set(), xpath_context::n, xpath_node_set_raw::remove_duplicates(), xpath_stack::result, xpath_node_set_raw::set_type(), xpath_node_set_raw::size(), step_fill(), and xpath_node_set_raw::type().

Referenced by eval_node_set().

                {
                        const axis_t axis = T::axis;
                        bool attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self);

                        xpath_node_set_raw ns;
                        ns.set_type((axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling) ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted);

                        if (_left)
                        {
                                xpath_node_set_raw s = _left->eval_node_set(c, stack);

                                // self axis preserves the original order
                                if (axis == axis_self) ns.set_type(s.type());

                                for (const xpath_node* it = s.begin(); it != s.end(); ++it)
                                {
                                        size_t size = ns.size();

                                        // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes
                                        if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted);
                                        
                                        if (it->node())
                                                step_fill(ns, it->node(), stack.result, v);
                                        else if (attributes)
                                                step_fill(ns, it->attribute(), it->parent(), stack.result, v);
                                                
                                        apply_predicates(ns, size, stack);
                                }
                        }
                        else
                        {
                                if (c.n.node())
                                        step_fill(ns, c.n.node(), stack.result, v);
                                else if (attributes)
                                        step_fill(ns, c.n.attribute(), c.n.parent(), stack.result, v);
                                
                                apply_predicates(ns, 0, stack);
                        }

                        // child, attribute and self axes always generate unique set of nodes
                        // for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice
                        if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted)
                                ns.remove_duplicates();

                        return ns;
                }
template<class T >
void xpath_ast_node::step_fill ( xpath_node_set_raw ns,
const xml_node &  n,
xpath_allocator alloc,
 
) [inline, private]

Definition at line 8224 of file pugixml.cpp.

References axis_ancestor, axis_ancestor_or_self, axis_attribute, axis_child, axis_descendant, axis_descendant_or_self, axis_following, axis_following_sibling, axis_parent, axis_preceding, axis_preceding_sibling, axis_self, node_is_ancestor(), and step_push().

Referenced by step_do(), and step_fill().

                {
                        const axis_t axis = T::axis;

                        switch (axis)
                        {
                        case axis_attribute:
                        {
                                for (xml_attribute a = n.first_attribute(); a; a = a.next_attribute())
                                        step_push(ns, a, n, alloc);
                                
                                break;
                        }
                        
                        case axis_child:
                        {
                                for (xml_node c = n.first_child(); c; c = c.next_sibling())
                                        step_push(ns, c, alloc);
                                        
                                break;
                        }
                        
                        case axis_descendant:
                        case axis_descendant_or_self:
                        {
                                if (axis == axis_descendant_or_self)
                                        step_push(ns, n, alloc);
                                        
                                xml_node cur = n.first_child();
                                
                                while (cur && cur != n)
                                {
                                        step_push(ns, cur, alloc);
                                        
                                        if (cur.first_child())
                                                cur = cur.first_child();
                                        else if (cur.next_sibling())
                                                cur = cur.next_sibling();
                                        else
                                        {
                                                while (!cur.next_sibling() && cur != n)
                                                        cur = cur.parent();
                                        
                                                if (cur != n) cur = cur.next_sibling();
                                        }
                                }
                                
                                break;
                        }
                        
                        case axis_following_sibling:
                        {
                                for (xml_node c = n.next_sibling(); c; c = c.next_sibling())
                                        step_push(ns, c, alloc);
                                
                                break;
                        }
                        
                        case axis_preceding_sibling:
                        {
                                for (xml_node c = n.previous_sibling(); c; c = c.previous_sibling())
                                        step_push(ns, c, alloc);
                                
                                break;
                        }
                        
                        case axis_following:
                        {
                                xml_node cur = n;

                                // exit from this node so that we don't include descendants
                                while (cur && !cur.next_sibling()) cur = cur.parent();
                                cur = cur.next_sibling();

                                for (;;)
                                {
                                        step_push(ns, cur, alloc);

                                        if (cur.first_child())
                                                cur = cur.first_child();
                                        else if (cur.next_sibling())
                                                cur = cur.next_sibling();
                                        else
                                        {
                                                while (cur && !cur.next_sibling()) cur = cur.parent();
                                                cur = cur.next_sibling();

                                                if (!cur) break;
                                        }
                                }

                                break;
                        }

                        case axis_preceding:
                        {
                                xml_node cur = n;

                                while (cur && !cur.previous_sibling()) cur = cur.parent();
                                cur = cur.previous_sibling();

                                for (;;)
                                {
                                        if (cur.last_child())
                                                cur = cur.last_child();
                                        else
                                        {
                                                // leaf node, can't be ancestor
                                                step_push(ns, cur, alloc);

                                                if (cur.previous_sibling())
                                                        cur = cur.previous_sibling();
                                                else
                                                {
                                                        do 
                                                        {
                                                                cur = cur.parent();
                                                                if (!cur) break;

                                                                if (!node_is_ancestor(cur, n)) step_push(ns, cur, alloc);
                                                        }
                                                        while (!cur.previous_sibling());

                                                        cur = cur.previous_sibling();

                                                        if (!cur) break;
                                                }
                                        }
                                }

                                break;
                        }
                        
                        case axis_ancestor:
                        case axis_ancestor_or_self:
                        {
                                if (axis == axis_ancestor_or_self)
                                        step_push(ns, n, alloc);

                                xml_node cur = n.parent();
                                
                                while (cur)
                                {
                                        step_push(ns, cur, alloc);
                                        
                                        cur = cur.parent();
                                }
                                
                                break;
                        }

                        case axis_self:
                        {
                                step_push(ns, n, alloc);

                                break;
                        }

                        case axis_parent:
                        {
                                if (n.parent()) step_push(ns, n.parent(), alloc);

                                break;
                        }
                                
                        default:
                                assert(!"Unimplemented axis");
                        }
                }
template<class T >
void xpath_ast_node::step_fill ( xpath_node_set_raw ns,
const xml_attribute &  a,
const xml_node &  p,
xpath_allocator alloc,
v 
) [inline, private]

Definition at line 8394 of file pugixml.cpp.

References _test, axis_ancestor, axis_ancestor_or_self, axis_descendant_or_self, axis_following, axis_parent, axis_preceding, axis_self, nodetest_type_node, step_fill(), and step_push().

                {
                        const axis_t axis = T::axis;

                        switch (axis)
                        {
                        case axis_ancestor:
                        case axis_ancestor_or_self:
                        {
                                if (axis == axis_ancestor_or_self && _test == nodetest_type_node) // reject attributes based on principal node type test
                                        step_push(ns, a, p, alloc);

                                xml_node cur = p;
                                
                                while (cur)
                                {
                                        step_push(ns, cur, alloc);
                                        
                                        cur = cur.parent();
                                }
                                
                                break;
                        }

                        case axis_descendant_or_self:
                        case axis_self:
                        {
                                if (_test == nodetest_type_node) // reject attributes based on principal node type test
                                        step_push(ns, a, p, alloc);

                                break;
                        }

                        case axis_following:
                        {
                                xml_node cur = p;
                                
                                for (;;)
                                {
                                        if (cur.first_child())
                                                cur = cur.first_child();
                                        else if (cur.next_sibling())
                                                cur = cur.next_sibling();
                                        else
                                        {
                                                while (cur && !cur.next_sibling()) cur = cur.parent();
                                                cur = cur.next_sibling();
                                                
                                                if (!cur) break;
                                        }

                                        step_push(ns, cur, alloc);
                                }

                                break;
                        }

                        case axis_parent:
                        {
                                step_push(ns, p, alloc);

                                break;
                        }

                        case axis_preceding:
                        {
                                // preceding:: axis does not include attribute nodes and attribute ancestors (they are the same as parent's ancestors), so we can reuse node preceding
                                step_fill(ns, p, alloc, v);
                                break;
                        }
                        
                        default:
                                assert(!"Unimplemented axis");
                        }
                }
void xpath_ast_node::step_push ( xpath_node_set_raw ns,
const xml_attribute &  a,
const xml_node &  parent,
xpath_allocator alloc 
) [inline, private]

Definition at line 8144 of file pugixml.cpp.

References _data, _test, nodetest_all, nodetest_all_in_namespace, nodetest_name, nodetest_type_node, xpath_node_set_raw::push_back(), starts_with(), and strequal().

Referenced by step_fill().

                {
                        if (!a) return;

                        const char_t* name = a.name();

                        // There are no attribute nodes corresponding to attributes that declare namespaces
                        // That is, "xmlns:..." or "xmlns"
                        if (starts_with(name, PUGIXML_TEXT("xmlns")) && (name[5] == 0 || name[5] == ':')) return;
                        
                        switch (_test)
                        {
                        case nodetest_name:
                                if (strequal(name, _data.nodetest)) ns.push_back(xpath_node(a, parent), alloc);
                                break;
                                
                        case nodetest_type_node:
                        case nodetest_all:
                                ns.push_back(xpath_node(a, parent), alloc);
                                break;
                                
                        case nodetest_all_in_namespace:
                                if (starts_with(name, _data.nodetest))
                                        ns.push_back(xpath_node(a, parent), alloc);
                                break;
                        
                        default:
                                ;
                        }
                }
void xpath_ast_node::step_push ( xpath_node_set_raw ns,
const xml_node &  n,
xpath_allocator alloc 
) [inline, private]

Definition at line 8175 of file pugixml.cpp.

References _data, _test, nodetest_all, nodetest_all_in_namespace, nodetest_name, nodetest_pi, nodetest_type_comment, nodetest_type_node, nodetest_type_pi, nodetest_type_text, xpath_node_set_raw::push_back(), starts_with(), and strequal().

                {
                        if (!n) return;

                        switch (_test)
                        {
                        case nodetest_name:
                                if (n.type() == node_element && strequal(n.name(), _data.nodetest)) ns.push_back(n, alloc);
                                break;
                                
                        case nodetest_type_node:
                                ns.push_back(n, alloc);
                                break;
                                
                        case nodetest_type_comment:
                                if (n.type() == node_comment)
                                        ns.push_back(n, alloc);
                                break;
                                
                        case nodetest_type_text:
                                if (n.type() == node_pcdata || n.type() == node_cdata)
                                        ns.push_back(n, alloc);
                                break;
                                
                        case nodetest_type_pi:
                                if (n.type() == node_pi)
                                        ns.push_back(n, alloc);
                                break;
                                                                        
                        case nodetest_pi:
                                if (n.type() == node_pi && strequal(n.name(), _data.nodetest))
                                        ns.push_back(n, alloc);
                                break;
                                
                        case nodetest_all:
                                if (n.type() == node_element)
                                        ns.push_back(n, alloc);
                                break;
                                
                        case nodetest_all_in_namespace:
                                if (n.type() == node_element && starts_with(n.name(), _data.nodetest))
                                        ns.push_back(n, alloc);
                                break;

                        default:
                                assert(!"Unknown axis");
                        } 
                }

Member Data Documentation

char xpath_ast_node::_axis [private]

Definition at line 7926 of file pugixml.cpp.

Referenced by eval_node_set().

union { ... } xpath_ast_node::_data [private]

Definition at line 7932 of file pugixml.cpp.

Referenced by apply_predicates(), eval_string(), eval_string_concat(), is_posinv(), and set_next().

char xpath_ast_node::_rettype [private]

Definition at line 7923 of file pugixml.cpp.

Referenced by eval_boolean(), eval_node_set(), eval_number(), eval_string(), and rettype().

char xpath_ast_node::_test [private]

Definition at line 7927 of file pugixml.cpp.

Referenced by step_fill(), and step_push().

char xpath_ast_node::_type [private]
const char_t* xpath_ast_node::nodetest

Definition at line 7943 of file pugixml.cpp.

Definition at line 7939 of file pugixml.cpp.

const char_t* xpath_ast_node::string

Definition at line 7937 of file pugixml.cpp.

xpath_variable* xpath_ast_node::variable

Definition at line 7941 of file pugixml.cpp.


The documentation for this class was generated from the following file:

Generated on Mon Sep 15 2014 01:23:55 for QuickFIX by doxygen 1.7.6.1 written by Dimitri van Heesch, © 1997-2001