📄 xpath_processor.cpp
字号:
else
v_push_int (atoi (S_literal . c_str ()), "primary number");
}
break;
case xpath_primary_expr_function_call :
v_execute_one (xpath_function_call, o_skip_only);
break;
}
break;
case xpath_function_call :
erpp_arg = NULL;
o_error = false;
try
{
if (u_sub)
{
// execute arguments
if (! o_skip_only)
{
erpp_arg = new expression_result * [u_variable];
memset (erpp_arg, 0, u_variable * sizeof (expression_result *));
}
for (u_arg = 0; u_arg < u_variable; u_arg++)
{
/// Compute each argument, and store them in a temporary list
v_execute_one (xpath_argument, o_skip_only);
if (! o_skip_only)
{
if (! xs_stack . u_get_size ())
throw execution_error (10);
erpp_arg [u_variable - u_arg - 1] = new expression_result (* xs_stack . erp_top ());
xs_stack . v_pop ();
}
}
}
v_execute_one (xpath_xml_q_name, o_skip_only);
if (! o_skip_only)
{
S_name = S_pop_string ();
v_execute_function (S_name, u_variable, erpp_arg);
}
}
catch (execution_error)
{
o_error = true;
}
if (erpp_arg)
{
for (u_arg = 0; u_arg < u_variable; u_arg++)
{
if (erpp_arg [u_arg])
delete erpp_arg [u_arg];
}
delete [] erpp_arg;
}
if (o_error)
throw execution_error (11);
break;
case xpath_xml_q_name :
switch (u_sub)
{
case xpath_xml_q_name_colon :
v_execute_one (xpath_xml_local_part, o_skip_only);
v_execute_one (xpath_xml_prefix, o_skip_only);
break;
case xpath_xml_q_name_simple :
v_execute_one (xpath_xml_local_part, o_skip_only);
break;
}
break;
case xpath_xml_local_part :
if (! o_skip_only)
v_push_string (S_literal);
break;
case xpath_xml_prefix :
if (! o_skip_only)
{
// we replace the current stack content (local_part) by the fully
// qualified XML name_ (prefix:local_part)
S_name = S_pop_string ();
S_literal += ":";
S_literal += S_name;
v_push_string (S_literal);
}
break;
case xpath_argument :
v_execute_one (xpath_expr, o_skip_only);
break;
case xpath_location_path :
switch (u_sub)
{
case xpath_location_path_rel :
v_execute_one (xpath_relative_location_path, o_skip_only);
break;
case xpath_location_path_abs :
v_execute_one (xpath_absolute_location_path, o_skip_only);
break;
}
break;
case xpath_relative_location_path :
switch (u_sub)
{
case xpath_relative_location_path_rel_step :
// RelativeLocationPath ::= RelativeLocationPath '/' Step
v_execute_one (xpath_relative_location_path, o_skip_only);
// v_execute_step (i_relative_action);
break;
case xpath_relative_location_path_rel_double_slash_step :
// RelativeLocationPath ::= RelativeLocationPath '//' Step
break;
case xpath_relative_location_path_step :
// RelativeLocationPath ::= Step
int i_dummy;
i_dummy = -2;
v_execute_step (i_dummy, o_skip_only);
break;
}
break;
case xpath_absolute_location_path :
switch (u_sub)
{
case xpath_absolute_location_path_slash :
// AbsoluteLocationPath ::= '/'
v_execute_absolute_path (u_variable, false, false);
break;
case xpath_absolute_location_path_slash_rel :
// AbsoluteLocationPath ::= '/' RelativeLocationPath
v_execute_absolute_path (u_variable, true, false);
break;
case xpath_absolute_location_path_abbrev :
// AbsoluteLocationPath ::= AbbreviatedAbsoluteLocationPath
v_execute_absolute_path (u_variable, true, true);
break;
}
break;
case xpath_axis_specifier :
switch (u_sub)
{
case xpath_axis_specifier_at :
// AxisSpecifier ::= '@'
if (! o_skip_only)
// will be used in the v_execute_step
v_push_int (1, "axis specifier is at");
break;
case xpath_axis_specifier_axis_name :
// AxisSpecifier ::= AxisName '::'
v_execute_one (xpath_axis_name, o_skip_only);
break;
case xpath_axis_specifier_empty :
if (! o_skip_only)
// will be used in the v_execute_step
v_push_int (0, "axis specifier is empty");
break;
}
break;
case xpath_axis_name :
if (! o_skip_only)
// will be used in the v_execute_step
v_push_int (u_variable, "axis is a name");
break;
case xpath_node_test :
// to do : processing instructions ???
switch (u_sub)
{
case xpath_node_test_reserved_keyword :
// will be used in the v_execute_step
if (! o_skip_only)
{
i_pop_int ();
v_push_int (u_variable, "axis is a keyword");
S_temp = "*";
v_push_string (S_temp);
}
break;
case xpath_node_test_pi :
break;
case xpath_node_test_pi_lit :
break;
case xpath_node_test_name_test :
v_execute_one (xpath_name_test, o_skip_only);
break;
}
break;
case xpath_predicate :
// [8] Predicate ::= '[' PredicateExpr ']'
v_execute_one (xpath_predicate_expr, o_skip_only);
break;
case xpath_predicate_expr :
// [9] PredicateExpr ::= Expr
v_execute_one (xpath_expr, o_skip_only);
break;
case xpath_name_test :
switch (u_sub)
{
case xpath_name_test_star :
if (! o_skip_only)
{
S_temp = "*";
v_push_string (S_temp);
}
break;
case xpath_name_test_ncname :
break;
case xpath_name_test_qname :
v_execute_one (xpath_xml_q_name, o_skip_only);
break;
}
break;
default :
throw execution_error (12);
}
}
/// Execute a full set of absolute/relative/relative/.. computation
void xpath_processor::v_execute_absolute_path (
unsigned u_action_position, ///< Position of the placeholder after the rule
bool o_with_rel, ///< true if there is some relative path
bool o_everywhere) ///< true if it's a '//' path
{
unsigned u_end_action;
int i_relative_action;
bool o_do_last;
u_end_action = u_action_position;
if (o_with_rel)
{
int i_1, i_2, i_3;
int i_bak_position, i_current, i_first, i_relative;
TIXML_STRING S_lit;
// compute position of the first_ (absolute) step
i_current = as_action_store . i_get_position ();
if (o_everywhere)
i_relative = i_current - 2;
else
i_relative = i_current - 1;
as_action_store . v_get (i_relative, i_1, i_2, i_3, S_lit);
if (i_1 == xpath_relative_location_path)
{
o_do_last = true;
i_first = i_3 - 1;
}
else
{
o_do_last = false;
i_first = i_relative;
}
// i_first = i_3 - 1;
i_bak_position = as_action_store . i_get_position ();
as_action_store . v_set_position (i_first);
if (o_everywhere)
i_relative_action = -1;
else
i_relative_action = 0;
v_execute_step (i_relative_action, false);
bool o_end = false;
do
{
i_relative--;
as_action_store . v_get (i_relative, i_1, i_2, i_3, S_lit);
if (i_1 != xpath_relative_location_path)
o_end = true;
else
{
as_action_store . v_set_position (i_3 - 1);
v_execute_step (i_relative_action, false);
}
} while (! o_end);
if (o_do_last)
{
// apply last_ one
as_action_store . v_set_position (i_relative);
v_execute_step (i_relative_action, false);
}
// resume the execution after the whole path construction
as_action_store . v_set_position ((int) u_end_action - 1);
}
}
/// One step execution
void xpath_processor ::v_execute_step (
int & i_relative_action, ///< Path position : -1 if first_ in a '//' path, 0 if first_ in a '/' path, > 0 if followers
bool o_skip_only)
{
bool o_by_name;
int i_axis_type, i_end_store, i_node_store, i_pred_store;
unsigned u_nb_node, u_node, u_pred, u_sub, u_variable;
xpath_construct xc_action;
TIXML_STRING S_literal, S_name;
const element * XEp_child, * XEp_elem;
const node * XNp_father;
const attribute * XAp_attrib;
const node * XNp_next, * XNp_parent;
node_set ns_source, ns_target;
if (! o_skip_only)
{
/// Initialize the source node_ set if it's the first_ step of a path
switch (i_relative_action)
{
case -2 :
// relative to context
ns_source . v_add_node_in_set (XEp_context);
i_relative_action = 1;
break;
case -1 :
// everywhere
ns_source . v_copy_selected_node_recursive_root_only (XNp_base_parent, XNp_base);
i_relative_action = 1;
break;
case 0 :
// first_ absolute
ns_source . v_add_node_in_set (XNp_base_parent);
i_relative_action = 1;
break;
default :
// second and following steps
ns_source = * (xs_stack . erp_top () -> nsp_get_node_set ());
xs_stack . v_pop ();
break;
}
}
// Pop our step action from the action placeholder
v_pop_one_action (xc_action, u_sub, u_variable, S_literal);
// Skip the predicates
i_pred_store = as_action_store . i_get_position ();
for (u_pred = 0; u_pred < u_variable; u_pred++)
v_execute_one (xpath_predicate, true);
i_node_store = as_action_store . i_get_position ();
// Skip the node_ test
v_execute_one (xpath_node_test, true);
// Run the axis
v_execute_one (xpath_axis_specifier, o_skip_only);
i_end_store = as_action_store . i_get_position ();
// Run the node_ test
as_action_store . v_set_position (i_node_store);
v_execute_one (xpath_node_test, o_skip_only);
as_action_store . v_set_position (i_pred_store);
if (! o_skip_only)
{
S_name = S_pop_string ();
o_by_name = ! (S_name == "*");
// Retrieve the archive flag stored by the xpath_axis_specifier rule execution
// o_attrib_flag = o_pop_bool ();
i_axis_type = i_pop_int ();
u_nb_node = ns_source . u_get_nb_node_in_set ();
for (u_node = 0; u_node < u_nb_node; u_node++)
{
if (! ns_source . o_is_attrib (u_node))
{
XNp_father = ns_source . XNp_get_node_in_set (u_node);
if (XNp_father)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -