📄 xpath_processor.cpp
字号:
{
case e_int :
case e_bool :
i_val = erpp_arg [0] -> i_get_int ();
break;
case e_double :
i_val = (int) floor (erpp_arg [0] -> d_get_double ());
break;
default :
i_val = 0;
break;
}
v_push_int (i_val, "floor");
}
/// XPath \b last_ function
void xpath_processor::v_function_last (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
const element * XEp_context;
if (u_nb_arg)
throw execution_error (20);
XEp_context = XEp_get_context ();
if (! XEp_context)
throw execution_error (21);
v_push_int (i_xml_family_size (XEp_context), "last()");
}
/// XPath \b name_ function
/// \n XPath spec: If the argument it omitted, it defaults to a node_-set with the context node_ as its only member.
void xpath_processor::v_function_name (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
TIXML_STRING S_res;
node_set * nsp_set;
switch (u_nb_arg)
{
case 0 :
// name_ of the context node_
XEp_context = XEp_get_context ();
S_res = XEp_context -> value ();
break;
case 1 :
// name_ of the argument
S_res = "";
if (erpp_arg [0] -> e_type == e_node_set)
{
nsp_set = erpp_arg [0] -> nsp_get_node_set ();
if (nsp_set -> u_get_nb_node_in_set ())
if (nsp_set -> o_is_attrib (0))
S_res = nsp_set -> XAp_get_attribute_in_set (0) -> name ();
else
S_res = nsp_set -> XNp_get_node_in_set (0) -> value ();
}
break;
default :
throw execution_error (22);
}
v_push_string (S_res);
}
/// XPath \b normalize-space function
void xpath_processor::v_function_normalize_space (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
TIXML_STRING S_arg, S_res;
if (u_nb_arg != 1)
throw execution_error (23);
S_arg = erpp_arg [0] -> S_get_string ();
S_res = S_remove_lead_trail (S_arg . c_str ());
v_push_string (S_res);
}
/// XPath \b not function
void xpath_processor::v_function_not (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
if (u_nb_arg != 1)
throw execution_error (24);
v_push_bool (! erpp_arg [0] -> o_get_bool ());
}
/// XPath \b position function
void xpath_processor::v_function_position (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
const element * XEp_context;
if (u_nb_arg)
throw execution_error (25);
XEp_context = XEp_get_context ();
if (! XEp_context)
throw execution_error (26);
v_push_int (i_xml_cardinality (XEp_context, o_is_context_by_name), "position()");
}
/// XPath \b starts-with function
void xpath_processor::v_function_starts_with (
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 (27);
S_arg_1 = erpp_arg [0] -> S_get_string ();
S_arg_2 = erpp_arg [1] -> S_get_string ();
v_push_bool (! strncmp (S_arg_1 . c_str (), S_arg_2 . c_str (), S_arg_2 . length ()));
}
/// XPath \b sttring-length function
void xpath_processor::v_function_string_length (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
TIXML_STRING S_arg;
if (u_nb_arg != 1)
throw execution_error (28);
S_arg = erpp_arg [0] -> S_get_string ();
v_push_int (S_arg . length (), "string-length");
}
/**
XPath \b substring function\n
Standard excerpt:\n
The substring function returns the substring of the first_ argument starting at the position specified in the second argument
with length specified in the third argument. For example, substring("12345",2,3) returns "234". If the third argument is not
specified, it returns the substring starting at the position specified in the second argument and continuing to the end of
the string. For example, substring("12345",2) returns "2345".
*/
void xpath_processor::v_function_substring (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
TIXML_STRING S_base, S_ret;
int i_length, i_start;
const char * cp_base;
char * cp_work;
if (u_nb_arg != 2 && u_nb_arg != 3)
throw execution_error (29);
S_base = erpp_arg [0] -> S_get_string ();
i_start = erpp_arg [1] -> i_get_int ();
if (u_nb_arg == 3)
i_length = erpp_arg [2] -> i_get_int ();
else
i_length = 0;
if (i_start < 1)
S_ret = "";
else
{
i_start--;
if (i_start >= (int) S_base . length ())
S_ret = "";
else
{
cp_base = S_base . c_str () + i_start;
if (u_nb_arg == 2 || (int) strlen (cp_base) <= i_length)
S_ret = cp_base;
else
{
cp_work = new char [i_length + 1];
strncpy (cp_work, cp_base, i_length);
cp_work [i_length] = 0;
S_ret = cp_work;
delete [] cp_work;
}
}
}
v_push_string (S_ret);
}
/// XPath \b sum function\n
/// Standard exerpt :\n
/// The sum function returns the sum, for each node_ in the argument node_-set,
/// of the result of converting the string-values of the node_ to a number.
void xpath_processor::v_function_sum (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
int i_sum;
double d_sum;
unsigned u_node;
node_set * nsp_set;
bool o_out_double;
if (u_nb_arg != 1)
throw execution_error (30);
i_sum = 0;
d_sum = 0.0;
o_out_double = false;
if (erpp_arg [0] -> e_type != e_node_set)
throw execution_error (31);
nsp_set = erpp_arg [0] -> nsp_get_node_set ();
assert (nsp_set);
for (u_node = 0; u_node < nsp_set -> u_get_nb_node_in_set (); u_node++)
{
i_sum += nsp_set -> i_get_value (u_node);
d_sum += nsp_set -> d_get_value (u_node);
if (strchr (nsp_set -> S_get_value (u_node) . c_str (), '.'))
o_out_double = true;
}
if (o_out_double)
v_push_double (d_sum);
else
v_push_int (i_sum, "sum()");
}
/// XPath \b text_ function
void xpath_processor::v_function_text (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
const element * XEp_context;
const node * XNp_child;
TIXML_STRING S_res;
if (u_nb_arg)
throw execution_error (38);
XEp_context = XEp_get_context ();
if (! XEp_context)
throw execution_error (39);
XNp_child = XEp_context -> first_child ();
while (XNp_child)
{
if (XNp_child -> type () == node::TEXT)
S_res += XNp_child -> value ();
XNp_child = XNp_child -> next_sibling ();
}
v_push_string (S_res);
}
/// XPath \b translate function\n
/// Standard exerpt :\n
///The translate function returns the first_ argument string with occurrences of
///characters in the second argument string replaced by the character at the
///corresponding position in the third argument string.
void xpath_processor::v_function_translate (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
TIXML_STRING S_translated;
char* cp_translated = NULL;
//pre-conditions
if (u_nb_arg != 3)
throw execution_error (40);
TIXML_STRING S_translate_me = erpp_arg [0] -> S_get_string ();
TIXML_STRING S_translation_table_lhs = erpp_arg [1] -> S_get_string ();
TIXML_STRING S_translation_table_rhs = erpp_arg [2] -> S_get_string ();
// Strings S_translation_table_lhs and S_translation_table_rhs represent
// the translation table's left hand side and right hand side respectively
// e.g. for "abc" "XYZ" ... we have the table
// "a "X
// b Y
// c Z
// " "
// lhs rhs
cp_translated = new char[ S_translate_me.length() + 1];
unsigned int u_write_at = 0 ;
for(unsigned int u_read_at = 0; u_read_at < S_translate_me.length() ; u_read_at++)
{
//search in the translation scheme table
unsigned int u_translation_rule_index = 0;
for(; u_translation_rule_index < S_translation_table_lhs.size(); u_translation_rule_index++)
{
// this also ensures that if we have multiple translation rules for a single character then only the first_ one is selected
if(S_translate_me[u_read_at] == S_translation_table_lhs [u_translation_rule_index])
{
//translation rule found for current character
break;
}
}
if( u_translation_rule_index < S_translation_table_lhs.size())
{
//the current character has a translation rule
if(u_translation_rule_index < S_translation_table_rhs.size())
{
cp_translated[u_write_at] = S_translation_table_rhs[u_translation_rule_index];
u_write_at++;
}
else
{
// else empty translation scheme
// so current charater skipped
}
}
else
{
//no_ translation scheme for current charater
//thus copy it as it is in cp_translated
cp_translated[u_write_at] = S_translate_me[u_read_at];
u_write_at++;
}
}
cp_translated [u_write_at] = 0;
S_translated = cp_translated;
delete [] cp_translated;
v_push_string(S_translated);
}
/// XPath \b true function
void xpath_processor::v_function_true (
unsigned u_nb_arg, ///< Nb of arguments
expression_result ** erpp_arg) ///< Argument list
{
if (u_nb_arg)
throw execution_error (32);
v_push_bool (true);
}
/**
This function is for internal use : evaluation of an equality expression \n
Standard excerpt :\n
If both objects to be compared are node_-sets, then the comparison will be true if and only if there is a node_ in the first_
node_-set and a node_ in the second node_-set such that the result of performing the comparison on the string-values of the
two nodes is true. \n
If one object to be compared is a node_-set and the other is a number, then the comparison will be true
if and only if there is a node_ in the node_-set such that the result of performing the comparison on the number to be compared
and on the result of converting the string-value_ of that node_ to a number using the number function is true. \n
If one object to be compared is a node_-set and the other is a string, then the comparison will be true if and only if there is a node_ in
the node_-set such that the result of performing the comparison on the string-value_ of the node_ and the other string is true. \n
If one object to be compared is a node_-set and the other is a boolean, then the comparison will be true if and only if the
result of performing the comparison on the boolean and on the result of converting the node_-set to a boolean using the boolean
function is true.\n
When neither object to be compared is a node_-set and the operator is = or !=, then the objects are compared by converting them
to a common type_ as follows and then comparing them.
- If at least one object to be compared is a boolean, then each object to be compared is converted to a boolean as if by
applying the boolean function.
- Otherwise, if at least one object to be compared is a number, then each object to be compared is converted to a number as
if by applying the number function.
- Otherwise, both objects to be compared are converted to strings as if by applying the string function. The = comparison will
be true if and only if the objects are equal; the != comparison will be true if and only if the objects are not equal.
- Numbers are compared for equality according to IEEE 754.
- Two booleans are equal if either both are true or both are false.
- Two strings are equal if and only if they consist of the same sequence of UCS characters.
*/
void xpath_processor::v_function_equal (expression_result ** erpp_arg)
{
bool o_res;
assert (erpp_arg);
assert (erpp_arg [0]);
assert (erpp_arg [1]);
if (erpp_arg [0] -> e_type == e_node_set)
if (erpp_arg [1] -> e_type == e_node_set)
v_function_equal_2_node (erpp_arg [0], erpp_arg [1]);
else
v_function_equal_node_and_other (erpp_arg [0], erpp_arg [1]);
else
if (erpp_arg [1] -> e_type == e_node_set)
v_function_equal_node_and_other (erpp_arg [1], erpp_arg [0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -