xpath_ast_node Class Reference
Collaboration diagram for xpath_ast_node:
[legend]

## 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_node & | operator= (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() [1/6]

xpath_ast_node::xpath_ast_node | ( | const xpath_ast_node & |  | ) |

private

## xpath_ast_node() [2/6]

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.

:
_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;
}

References _data, and ast_string_constant.

## xpath_ast_node() [3/6]

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.

:
_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;
}

References _data, and ast_number_constant.

## xpath_ast_node() [4/6]

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.

:
_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;
}

References _data, and ast_variable.

## xpath_ast_node() [5/6]

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() [6/6]

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.

:
_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;
}

References _data.

## Member Function Documentation

## apply_predicate()

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.

{
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);
}

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().

## apply_predicates()

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.

{
if (ns.size() == first) return;
for (xpath_ast_node* pred = _right; pred; pred = pred->_next)
{
apply_predicate(ns, first, pred->_left, stack);
}
}

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

Referenced by step_do().

## compare_eq()

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.

{
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;
}

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().

## compare_rel()

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.

{
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;
}
}

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().

## eval_boolean()

bool xpath_ast_node::eval_boolean | ( | const xpath_context & | c,
|  | const xpath_stack & | stack
| ) |  |

inline

Definition at line 8561 of file pugixml.cpp.

{
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;
}
}
}
}

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().

## eval_node_set()

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.

{
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();
}
}

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().

## eval_number()

double xpath_ast_node::eval_number | ( | const xpath_context & | c,
|  | const xpath_stack & | stack
| ) |  |

inline

Definition at line 8690 of file pugixml.cpp.

{
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;
}
}
}
}

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().

## eval_string()

xpath_string xpath_ast_node::eval_string | ( | const xpath_context & | c,
|  | const xpath_stack & | stack
| ) |  |

inline

Definition at line 8876 of file pugixml.cpp.

{
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();
}
}
}
}

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().

## eval_string_concat()

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.

{
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);
}

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

Referenced by eval_string().

## is_posinv()

bool xpath_ast_node::is_posinv | ( |  | ) |

inline

Definition at line 9221 of file pugixml.cpp.

{
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;
}
}

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().

## operator=()

xpath_ast_node& xpath_ast_node::operator= | ( | const xpath_ast_node & |  | ) |

private

## rettype()

xpath_value_type xpath_ast_node::rettype | ( |  | ) | const

inline

Definition at line 9252 of file pugixml.cpp.

{
return static_cast<xpath_value_type>(_rettype);
}

References _rettype.

Referenced by apply_predicate(), compare_eq(), compare_rel(), xpath_parser::parse_expression_rec(), xpath_parser::parse_filter_expression(), xpath_parser::parse_path_or_unary_expression(), and xpath_parser::parse_step().

## set_next()

void xpath_ast_node::set_next | ( | xpath_ast_node * | value | ) |

inline

Definition at line 8551 of file pugixml.cpp.

{
_next = value;
}

References _next.

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

## set_right()

void xpath_ast_node::set_right | ( | xpath_ast_node * | value | ) |

inline

Definition at line 8556 of file pugixml.cpp.

{
_right = value;
}

References _right.

Referenced by xpath_parser::parse_step().

## step_do()

template<class T >

xpath_node_set_raw xpath_ast_node::step_do | ( | const xpath_context & | c,
|  | const xpath_stack & | stack,
|  | T | v
| ) |  |

inline private

Definition at line 8470 of file pugixml.cpp.

{
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;
}

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().

## step_fill() [1/2]

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,
|  | T | v
| ) |  |

inline private

Definition at line 8394 of file pugixml.cpp.

{
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");
}
}

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().

## step_fill() [2/2]

template<class T >

void xpath_ast_node::step_fill | ( | xpath_node_set_raw & | ns,
|  | const xml_node & | n,
|  | xpath_allocator * | alloc,
|  | T |
| ) |  |

inline private

Definition at line 8224 of file pugixml.cpp.

{
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");
}
}

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().

## step_push() [1/2]

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.

{
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:
;
}
}

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().

## step_push() [2/2]

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.

{
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");
}
}

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().

## Member Data Documentation

## _axis

char xpath_ast_node::_axis

private

Definition at line 7926 of file pugixml.cpp.

Referenced by eval_node_set().

## _data

union { ... } xpath_ast_node::_data

Referenced by eval_boolean(), eval_node_set(), eval_number(), eval_string(), step_push(), and xpath_ast_node().

## _left

xpath_ast_node* xpath_ast_node::_left

private

Definition at line 7930 of file pugixml.cpp.

Referenced by eval_boolean(), eval_node_set(), eval_number(), eval_string(), eval_string_concat(), is_posinv(), and step_do().

## _next

xpath_ast_node* xpath_ast_node::_next

private

Definition at line 7932 of file pugixml.cpp.

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

## _rettype

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().

## _right

xpath_ast_node* xpath_ast_node::_right

private

Definition at line 7931 of file pugixml.cpp.

Referenced by apply_predicates(), eval_boolean(), eval_node_set(), eval_number(), eval_string(), eval_string_concat(), is_posinv(), and set_right().

## _test

char xpath_ast_node::_test

private

Definition at line 7927 of file pugixml.cpp.

Referenced by step_fill(), and step_push().

## _type

char xpath_ast_node::_type

private

Definition at line 7922 of file pugixml.cpp.

Referenced by eval_boolean(), eval_node_set(), eval_number(), eval_string(), eval_string_concat(), and is_posinv().

## nodetest

const char_t* xpath_ast_node::nodetest

Definition at line 7943 of file pugixml.cpp.

## number

double xpath_ast_node::number

Definition at line 7939 of file pugixml.cpp.

## string

const char_t* xpath_ast_node::string

Definition at line 7937 of file pugixml.cpp.

## variable

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:

- pugixml.cpp

xpath_context
Definition: pugixml.cpp:7454
namespace_uri
const PUGI__FN char_t * namespace_uri(const xml_node &node)
Definition: pugixml.cpp:7053
xpath_ast_node::apply_predicates
void apply_predicates(xpath_node_set_raw &ns, size_t first, const xpath_stack &stack)
Definition: pugixml.cpp:8134
axis_descendant
@ axis_descendant
Definition: pugixml.cpp:7887
axis_ancestor_or_self
@ axis_ancestor_or_self
Definition: pugixml.cpp:7884
xpath_node_set_raw::end
xpath_node * end() const
Definition: pugixml.cpp:7357
local_name
const PUGI__FN char_t * local_name(const xpath_node &node)
Definition: pugixml.cpp:7022
ast_func_translate
@ ast_func_translate
Definition: pugixml.cpp:7865
ast_func_last
@ ast_func_last
Definition: pugixml.cpp:7842
xpath_node_set_raw::sort_do
void sort_do()
Definition: pugixml.cpp:7421
xpath_ast_node::step_do
xpath_node_set_raw step_do(const xpath_context &c, const xpath_stack &stack, T v)
Definition: pugixml.cpp:8470
ast_func_starts_with
@ ast_func_starts_with
Definition: pugixml.cpp:7855
round_nearest_nzero
PUGI__FN double round_nearest_nzero(double value)
Definition: pugixml.cpp:7010
ast_number_constant
@ ast_number_constant
Definition: pugixml.cpp:7840
ast_op_add
@ ast_op_add
Definition: pugixml.cpp:7829
xpath_node_set_raw::push_back
void push_back(const xpath_node &node, xpath_allocator *alloc)
Definition: pugixml.cpp:7377
ast_op_divide
@ ast_op_divide
Definition: pugixml.cpp:7832
xpath_context::position
size_t position
Definition: pugixml.cpp:7457
ast_op_equal
@ ast_op_equal
Definition: pugixml.cpp:7823
ast_func_name_0
@ ast_func_name_0
Definition: pugixml.cpp:7850
equal_to
Definition: pugixml.cpp:5959
not_equal_to
Definition: pugixml.cpp:5967
xpath_node_set_raw::truncate
void truncate(xpath_node *pos)
Definition: pugixml.cpp:7426
xpath_node_set_raw::set_type
void set_type(xpath_node_set::type_t value)
Definition: pugixml.cpp:7446
xpath_node_set_raw::first
xpath_node first() const
Definition: pugixml.cpp:7372
xpath_node_set_raw::empty
bool empty() const
Definition: pugixml.cpp:7362
xpath_ast_node::step_push
void step_push(xpath_node_set_raw &ns, const xml_attribute &a, const xml_node &parent, xpath_allocator *alloc)
Definition: pugixml.cpp:8144
ast_func_local_name_1
@ ast_func_local_name_1
Definition: pugixml.cpp:7847
xpath_ast_node::_right
xpath_ast_node * _right
Definition: pugixml.cpp:7931
ast_func_id
@ ast_func_id
Definition: pugixml.cpp:7845
ast_filter_posinv
@ ast_filter_posinv
Definition: pugixml.cpp:7838
ast_op_less
@ ast_op_less
Definition: pugixml.cpp:7825
xpath_ast_node
Definition: pugixml.cpp:7918
ast_op_union
@ ast_op_union
Definition: pugixml.cpp:7835
ast_op_not_equal
@ ast_op_not_equal
Definition: pugixml.cpp:7824
ast_func_substring_after
@ ast_func_substring_after
Definition: pugixml.cpp:7858
xpath_ast_node::rettype
xpath_value_type rettype() const
Definition: pugixml.cpp:9252
qualified_name
const PUGI__FN char_t * qualified_name(const xpath_node &node)
Definition: pugixml.cpp:7017
swap
void swap(T &lhs, T &rhs)
Definition: pugixml.cpp:5991
ast_func_namespace_uri_1
@ ast_func_namespace_uri_1
Definition: pugixml.cpp:7849
ast_func_position
@ ast_func_position
Definition: pugixml.cpp:7843
xpath_stack
Definition: pugixml.cpp:6362
axis_ancestor
@ axis_ancestor
Definition: pugixml.cpp:7883
convert_string_to_number
PUGI__FN double convert_string_to_number(const char_t *string)
Definition: pugixml.cpp:6968
axis_preceding
@ axis_preceding
Definition: pugixml.cpp:7893
xpath_ast_node::eval_string
xpath_string eval_string(const xpath_context &c, const xpath_stack &stack)
Definition: pugixml.cpp:8876
ast_op_negate
@ ast_op_negate
Definition: pugixml.cpp:7834
xpath_node_set_raw::append
void append(const xpath_node *begin_, const xpath_node *end_, xpath_allocator *alloc)
Definition: pugixml.cpp:7399
ast_func_local_name_0
@ ast_func_local_name_0
Definition: pugixml.cpp:7846
xpath_context::size
size_t size
Definition: pugixml.cpp:7457
starts_with
PUGI__NS_END PUGI__NS_BEGIN PUGI__FN bool starts_with(const char_t *string, const char_t *pattern)
Definition: pugixml.cpp:6534
ast_func_string_1
@ ast_func_string_1
Definition: pugixml.cpp:7853
xpath_ast_node::eval_boolean
bool eval_boolean(const xpath_context &c, const xpath_stack &stack)
Definition: pugixml.cpp:8561
xpath_ast_node::_test
char _test
Definition: pugixml.cpp:7927
axis_namespace
@ axis_namespace
Definition: pugixml.cpp:7891
nodetest_all
@ nodetest_all
Definition: pugixml.cpp:7907
ast_func_number_1
@ ast_func_number_1
Definition: pugixml.cpp:7872
nodetest_type_comment
@ nodetest_type_comment
Definition: pugixml.cpp:7903
ast_func_boolean
@ ast_func_boolean
Definition: pugixml.cpp:7866
xpath_ast_node::_axis
char _axis
Definition: pugixml.cpp:7926
ast_func_concat
@ ast_func_concat
Definition: pugixml.cpp:7854
xpath_ast_node::eval_node_set
xpath_node_set_raw eval_node_set(const xpath_context &c, const xpath_stack &stack)
Definition: pugixml.cpp:9094
axis_following_sibling
@ axis_following_sibling
Definition: pugixml.cpp:7890
ast_func_number_0
@ ast_func_number_0
Definition: pugixml.cpp:7871
nodetest_type_node
@ nodetest_type_node
Definition: pugixml.cpp:7902
xpath_ast_node::_type
char _type
Definition: pugixml.cpp:7922
ast_func_substring_3
@ ast_func_substring_3
Definition: pugixml.cpp:7860
ast_op_greater
@ ast_op_greater
Definition: pugixml.cpp:7826
ast_step
@ ast_step
Definition: pugixml.cpp:7877
ast_func_contains
@ ast_func_contains
Definition: pugixml.cpp:7856
xpath_string::data
char_t * data(xpath_allocator *alloc)
Definition: pugixml.cpp:6494
nodetest_name
@ nodetest_name
Definition: pugixml.cpp:7901
xpath_ast_node::apply_predicate
void apply_predicate(xpath_node_set_raw &ns, size_t first, xpath_ast_node *expr, const xpath_stack &stack)
Definition: pugixml.cpp:8108
ast_op_greater_or_equal
@ ast_op_greater_or_equal
Definition: pugixml.cpp:7828
ast_variable
@ ast_variable
Definition: pugixml.cpp:7841
ast_filter
@ ast_filter
Definition: pugixml.cpp:7837
xpath_ast_node::eval_number
double eval_number(const xpath_context &c, const xpath_stack &stack)
Definition: pugixml.cpp:8690
xpath_allocator_capture
Definition: pugixml.cpp:6347
ast_op_multiply
@ ast_op_multiply
Definition: pugixml.cpp:7831
axis_following
@ axis_following
Definition: pugixml.cpp:7889
normalize_space
PUGI__FN void normalize_space(char_t *buffer)
Definition: pugixml.cpp:7097
ast_func_lang
@ ast_func_lang
Definition: pugixml.cpp:7870
nodetest_type_text
@ nodetest_type_text
Definition: pugixml.cpp:7905
ast_func_true
@ ast_func_true
Definition: pugixml.cpp:7868
round_nearest
PUGI__FN double round_nearest(double value)
Definition: pugixml.cpp:7005
xpath_ast_node::_rettype
char _rettype
Definition: pugixml.cpp:7923
nodetest_type_pi
@ nodetest_type_pi
Definition: pugixml.cpp:7904
xpath_ast_node::_data
union xpath_ast_node::@7 _data
ast_op_less_or_equal
@ ast_op_less_or_equal
Definition: pugixml.cpp:7827
ast_func_substring_2
@ ast_func_substring_2
Definition: pugixml.cpp:7859
ast_func_substring_before
@ ast_func_substring_before
Definition: pugixml.cpp:7857
xpath_ast_node::_left
xpath_ast_node * _left
Definition: pugixml.cpp:7930
xpath_ast_node::compare_eq
static bool compare_eq(xpath_ast_node *lhs, xpath_ast_node *rhs, const xpath_context &c, const xpath_stack &stack, const Comp &comp)
Definition: pugixml.cpp:7949
string_value
PUGI__FN xpath_string string_value(const xpath_node &na, xpath_allocator *alloc)
Definition: pugixml.cpp:6570
ast_func_normalize_space_0
@ ast_func_normalize_space_0
Definition: pugixml.cpp:7863
axis_preceding_sibling
@ axis_preceding_sibling
Definition: pugixml.cpp:7894
xpath_stack::result
xpath_allocator * result
Definition: pugixml.cpp:6364
less_equal
Definition: pugixml.cpp:5983
xpath_ast_node::compare_rel
static bool compare_rel(xpath_ast_node *lhs, xpath_ast_node *rhs, const xpath_context &c, const xpath_stack &stack, const Comp &comp)
Definition: pugixml.cpp:8037
convert_number_to_string
PUGI__FN xpath_string convert_number_to_string(double value, xpath_allocator *alloc)
Definition: pugixml.cpp:6871
axis_parent
@ axis_parent
Definition: pugixml.cpp:7892
ast_func_normalize_space_1
@ ast_func_normalize_space_1
Definition: pugixml.cpp:7864
strequal
PUGI__FN bool strequal(const char_t *src, const char_t *dst)
Definition: pugixml.cpp:188
ast_func_not
@ ast_func_not
Definition: pugixml.cpp:7867
convert_number_to_boolean
PUGI__FN bool convert_number_to_boolean(double value)
Definition: pugixml.cpp:6812
nodetest_pi
@ nodetest_pi
Definition: pugixml.cpp:7906
ast_func_count
@ ast_func_count
Definition: pugixml.cpp:7844
xpath_string::length
size_t length() const
Definition: pugixml.cpp:6489
tolower_ascii
PUGI__FN char_t tolower_ascii(char_t ch)
Definition: pugixml.cpp:6565
axis_to_type
Definition: pugixml.cpp:7911
node_is_ancestor
PUGI__FN bool node_is_ancestor(xml_node parent, xml_node node)
Definition: pugixml.cpp:6660
ast_func_floor
@ ast_func_floor
Definition: pugixml.cpp:7874
xpath_node_set_raw::remove_duplicates
void remove_duplicates()
Definition: pugixml.cpp:7433
ast_func_namespace_uri_0
@ ast_func_namespace_uri_0
Definition: pugixml.cpp:7848
xpath_context::n
xpath_node n
Definition: pugixml.cpp:7456
less
Definition: pugixml.cpp:5975
xpath_node_set_raw
Definition: pugixml.cpp:7339
xpath_ast_node::step_fill
void step_fill(xpath_node_set_raw &ns, const xml_node &n, xpath_allocator *alloc, T)
Definition: pugixml.cpp:8224
xpath_string_const
PUGI__FN xpath_string xpath_string_const(const char_t *str)
Definition: pugixml.cpp:6527
ast_func_false
@ ast_func_false
Definition: pugixml.cpp:7869
xpath_node_set_raw::begin
xpath_node * begin() const
Definition: pugixml.cpp:7352
xpath_ast_node::is_posinv
bool is_posinv()
Definition: pugixml.cpp:9221
axis_t
axis_t
Definition: pugixml.cpp:7881
find_substring
const PUGI__FN char_t * find_substring(const char_t *s, const char_t *p)
Definition: pugixml.cpp:6554
nodetest_all_in_namespace
@ nodetest_all_in_namespace
Definition: pugixml.cpp:7908
xpath_allocator::allocate
void * allocate(size_t size)
Definition: pugixml.cpp:6250
ast_func_name_1
@ ast_func_name_1
Definition: pugixml.cpp:7851
xpath_string::empty
bool empty() const
Definition: pugixml.cpp:6506
ast_func_string_0
@ ast_func_string_0
Definition: pugixml.cpp:7852
ast_func_string_length_0
@ ast_func_string_length_0
Definition: pugixml.cpp:7861
ast_func_ceiling
@ ast_func_ceiling
Definition: pugixml.cpp:7875
ast_func_round
@ ast_func_round
Definition: pugixml.cpp:7876
axis_attribute
@ axis_attribute
Definition: pugixml.cpp:7885
ast_step_root
@ ast_step_root
Definition: pugixml.cpp:7878
ast_op_and
@ ast_op_and
Definition: pugixml.cpp:7822
xpath_node_set_raw::size
size_t size() const
Definition: pugixml.cpp:7367
ast_func_sum
@ ast_func_sum
Definition: pugixml.cpp:7873
xpath_ast_node::_next
xpath_ast_node * _next
Definition: pugixml.cpp:7932
axis_descendant_or_self
@ axis_descendant_or_self
Definition: pugixml.cpp:7888
ast_string_constant
@ ast_string_constant
Definition: pugixml.cpp:7839
ast_op_subtract
@ ast_op_subtract
Definition: pugixml.cpp:7830
ast_op_mod
@ ast_op_mod
Definition: pugixml.cpp:7833
translate
PUGI__FN void translate(char_t *buffer, const char_t *from, const char_t *to)
Definition: pugixml.cpp:7123
xpath_string
Definition: pugixml.cpp:6402
ast_func_string_length_1
@ ast_func_string_length_1
Definition: pugixml.cpp:7862
xpath_string::c_str
const char_t * c_str() const
Definition: pugixml.cpp:6484
ast_op_or
@ ast_op_or
Definition: pugixml.cpp:7821
xpath_ast_node::eval_string_concat
xpath_string eval_string_concat(const xpath_context &c, const xpath_stack &stack)
Definition: pugixml.cpp:8827
axis_self
@ axis_self
Definition: pugixml.cpp:7895
is_nan
PUGI__FN bool is_nan(double value)
Definition: pugixml.cpp:6767
xpath_string::uses_heap
bool uses_heap() const
Definition: pugixml.cpp:6521
ast_predicate
@ ast_predicate
Definition: pugixml.cpp:7836
axis_child
@ axis_child
Definition: pugixml.cpp:7886
xpath_stack::temp
xpath_allocator * temp
Definition: pugixml.cpp:6365
xpath_node_set_raw::type
xpath_node_set::type_t type() const
Definition: pugixml.cpp:7441