📄 xpath_processor.cpp
字号:
switch (i_axis_type)
{
case 0 :
case lex_child :
// none
XEp_child = XNp_father -> first_child_element ();
while (XEp_child)
{
ns_target . v_add_node_in_set_if_name_or_star (XEp_child, S_name);
XEp_child = XEp_child -> next_sibling_element ();
}
break;
case 1 :
case lex_attribute :
// @
if (XNp_father -> to_element ())
XAp_attrib = XNp_father -> to_element () -> first_attribute ();
else
XAp_attrib = NULL;
while (XAp_attrib)
{
ns_target . v_add_attrib_in_set_if_name_or_star (XAp_attrib, S_name);
XAp_attrib = XAp_attrib -> next ();
}
break;
case lex_parent :
XNp_parent = XNp_father -> parent ();
if (XNp_parent)
ns_target . v_add_node_in_set_if_name_or_star (XNp_parent, S_name);
break;
case lex_ancestor :
XNp_parent = XNp_father -> parent ();
// we have to exclude our own dummy parent_
while (XNp_parent && XNp_parent != XNp_base_parent)
{
ns_target . v_add_node_in_set_if_name_or_star (XNp_parent, S_name);
XNp_parent = XNp_parent -> parent ();
}
break;
case lex_ancestor_or_self :
if (XNp_father -> to_element () && XNp_father != XNp_base_parent)
ns_target . v_add_node_in_set_if_name_or_star (XNp_father, S_name);
XNp_parent = XNp_father -> parent ();
while (XNp_parent && XNp_parent != XNp_base_parent)
{
ns_target . v_add_node_in_set_if_name_or_star (XNp_parent, S_name);
XNp_parent = XNp_parent -> parent ();
}
break;
case lex_following_sibling :
XNp_next = XNp_father -> next_sibling_element ();
while (XNp_next)
{
ns_target . v_add_node_in_set_if_name_or_star (XNp_next, S_name);
XNp_next = XNp_next -> next_sibling_element ();
}
break;
case lex_preceding_sibling :
XNp_next = XNp_father -> previous_sibling ();
while (XNp_next)
{
if (XNp_next -> type () == node::ELEMENT)
ns_target . v_add_node_in_set_if_name_or_star (XNp_next, S_name);
XNp_next = XNp_next -> previous_sibling ();
}
break;
case lex_descendant :
if (XNp_father -> to_element ())
{
if (S_name == "*")
ns_target . v_copy_selected_node_recursive_no_attrib (XNp_father, NULL);
else
ns_target . v_copy_selected_node_recursive_no_attrib (XNp_father, S_name . c_str ());
}
break;
case lex_descendant_or_self :
if (XNp_father -> to_element ())
{
if (XNp_father != XNp_base_parent)
ns_target . v_add_node_in_set_if_name_or_star (XNp_father, S_name);
if (S_name == "*")
ns_target . v_copy_selected_node_recursive_no_attrib (XNp_father, NULL);
else
ns_target . v_copy_selected_node_recursive_no_attrib (XNp_father, S_name . c_str ());
}
break;
case lex_self :
if (XNp_father -> to_element ())
{
if (XNp_father != XNp_base_parent && XNp_father -> to_element ())
ns_target . v_add_node_in_set_if_name_or_star (XNp_father, S_name);
}
break;
case lex_following :
ns_target . v_add_all_foll_node (XNp_father, S_name);
break;
case lex_preceding :
ns_target . v_add_all_prec_node (XNp_father, S_name);
break;
case lex_comment :
XNp_next = XNp_father -> first_child ();
while (XNp_next)
{
if (XNp_next -> type () == node::COMMENT)
ns_target . v_add_node_in_set (XNp_next);
XNp_next = XNp_next -> next_sibling ();
}
break;
case lex_text :
XNp_next = XNp_father -> first_child ();
while (XNp_next)
{
if (XNp_next -> type () == node::TEXT)
ns_target . v_add_node_in_set (XNp_next);
XNp_next = XNp_next -> next_sibling ();
}
break;
case lex_node :
XNp_next = XNp_father -> first_child ();
while (XNp_next)
{
ns_target . v_add_node_in_set (XNp_next);
XNp_next = XNp_next -> next_sibling ();
}
break;
default :
// an axis name_ followed by '::'
throw error_not_yet ();
break;
}
}
}
}
if (u_variable)
{
// we have predicates to apply
node_set ns_after_predicate;
for (u_node = 0; u_node < ns_target .u_get_nb_node_in_set (); u_node++)
{
if (! ns_target . o_is_attrib (u_node))
{
XEp_elem = ns_target . XNp_get_node_in_set (u_node) -> to_element ();
if (XEp_elem)
{
as_action_store . v_set_position (i_pred_store);
if (o_check_predicate (XEp_elem, o_by_name))
ns_after_predicate . v_add_node_in_set (XEp_elem);
}
}
}
v_push_node_set (& ns_after_predicate);
}
else
v_push_node_set (& ns_target);
}
as_action_store . v_set_position (i_end_store);
}
/// Spec extract :
/// \n A PredicateExpr is evaluated by evaluating the Expr and converting the result to a
/// boolean. If the result is a number, the result will be converted to true if the number
/// is equal to the context position and will be converted to false otherwise; if the result
/// is not a number, then the result will be converted as if by a call to the boolean function.
/// Thus a location path para[3] is equivalent to para[position()=3].
bool xpath_processor::o_check_predicate (const element * XEp_child, bool o_by_name)
{
expression_result * erp_top;
bool o_keep;
v_set_context (XEp_child, o_by_name);
v_execute_one (xpath_predicate, false);
v_set_context (NULL, false);
erp_top = xs_stack . erp_top ();
switch (erp_top -> e_type)
{
case e_double :
case e_int :
o_keep = (erp_top -> i_get_int () == i_xml_cardinality (XEp_child, o_by_name));
break;
default :
o_keep = erp_top -> o_get_bool ();
break;
}
xs_stack . v_pop ();
return o_keep;
}
/**
Execute an XPath function. The arguments are in normal order in erpp_arg\n
Calls one of the following :
- v_function_ceiling
- v_function_concat
- v_function_contains
- v_function_count
- v_function_false
- v_function_floor
- v_function_last
- v_function_name
- v_function_normalize_space
- v_function_not
- v_function_position
- v_function_starts_with
- v_function_string_length
- v_function_substring
- v_function_sum
- v_function_true
*/
void xpath_processor::v_execute_function (
TIXML_STRING & S_name, ///< Function name_
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
if (S_name == "ceiling")
v_function_ceiling (u_nb_arg, erpp_arg);
else
if (S_name == "concat")
v_function_concat (u_nb_arg, erpp_arg);
else
if (S_name == "contains")
v_function_contains (u_nb_arg, erpp_arg);
else
if (S_name == "count")
v_function_count (u_nb_arg, erpp_arg);
else
if (S_name == "false")
v_function_false (u_nb_arg, erpp_arg);
else
if (S_name == "floor")
v_function_floor (u_nb_arg, erpp_arg);
else
if (S_name == "last")
v_function_last (u_nb_arg, erpp_arg);
else
if (S_name == "name")
v_function_name (u_nb_arg, erpp_arg);
else
if (S_name == "normalize-space")
v_function_normalize_space (u_nb_arg, erpp_arg);
else
if (S_name == "not")
v_function_not (u_nb_arg, erpp_arg);
else
if (S_name == "position")
v_function_position (u_nb_arg, erpp_arg);
else
if (S_name == "starts-with")
v_function_starts_with (u_nb_arg, erpp_arg);
else
if (S_name == "string-length")
v_function_string_length (u_nb_arg, erpp_arg);
else
if (S_name == "substring")
v_function_substring (u_nb_arg, erpp_arg);
else
if (S_name == "sum")
v_function_sum (u_nb_arg, erpp_arg);
else
if (S_name == "text")
v_function_text (u_nb_arg, erpp_arg);
else
if (S_name == "translate")
v_function_translate (u_nb_arg, erpp_arg);
else
if (S_name == "true")
v_function_true (u_nb_arg, erpp_arg);
else
throw execution_error (13);
}
/// XPath \b ceiling function
void xpath_processor::v_function_ceiling (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
int i_val;
if (u_nb_arg != 1)
throw execution_error (14);
switch (erpp_arg [0] -> e_type)
{
case e_int :
case e_bool :
i_val = erpp_arg [0] -> i_get_int ();
break;
case e_double :
i_val = (int) ceil (erpp_arg [0] -> d_get_double ());
break;
default :
i_val = 0;
break;
}
v_push_int (i_val, "ceiling");
}
/// XPath \b concat function
void xpath_processor::v_function_concat (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
TIXML_STRING S_res;
unsigned u_arg;
if (! u_nb_arg)
throw execution_error (15);
S_res = erpp_arg [0] -> S_get_string ();
for (u_arg = 1; u_arg < u_nb_arg; u_arg++)
S_res += erpp_arg [u_arg] -> S_get_string () . c_str ();
v_push_string (S_res);
}
/// XPath \b contains function
void xpath_processor::v_function_contains (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
TIXML_STRING S_arg_1, S_arg_2;
if (u_nb_arg != 2)
throw execution_error (16);
S_arg_1 = erpp_arg [0] -> S_get_string ();
S_arg_2 = erpp_arg [1] -> S_get_string ();
v_push_bool (strstr (S_arg_1 . c_str (), S_arg_2 . c_str ()) ? true : false);
}
/// XPath \b count function
void xpath_processor::v_function_count (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
int i_res;
if (! u_nb_arg)
throw execution_error (17);
if (erpp_arg [0] -> e_type != e_node_set)
i_res = 0;
else
i_res = erpp_arg [0] -> nsp_get_node_set () -> u_get_nb_node_in_set ();
v_push_int (i_res, "count result");
}
/// XPath \b false function
void xpath_processor::v_function_false (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
if (u_nb_arg)
throw execution_error (18);
v_push_bool (false);
}
/// XPath \b floor function
void xpath_processor::v_function_floor (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
int i_val;
if (u_nb_arg != 1)
throw execution_error (19);
switch (erpp_arg [0] -> e_type)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -