⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpath_processor.cpp

📁 j2me is based on j2mepolish, client & server for mobile application.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
www.sourceforge.net/projects/tinyxpath_
Copyright (c) 2002-2004 Yves Berquin (yvesb@users.sourceforge.net)

This software is provided 'as-is', without any express or implied
warranty. In no_ event will the authors be held liable for any
damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.
*/

/*
 @history:
 
 Modified on  16 December 2006 by  Aman Aggarwal
 ::Added support for Expressions like ( Expr or Expr or Expr) 
 Modified on 18 December 2006 by Aman Aggarwal
 ::Added support for translate()  
*/
#include <math.h>
#include "xpath_processor.h"
#include "xml_util.h"

using namespace aux::xml;

#ifdef TINYXPATH_DEBUG
   // only define DUMP_ACTION if TINYXPATH_DEBUG is defined
   #define DUMP_ACTION
#endif

/// xpath_processor constructor
xpath_processor::xpath_processor (
   const node * XNp_source_tree,  ///< Source XML tree
   const char * cp_xpath_expr)         ///< XPath expression
      : xpath_stream (cp_xpath_expr)
{
   if (XNp_source_tree && cp_xpath_expr)
      XNp_base = XNp_source_tree;
   else
      XNp_base = NULL;
   er_result . v_set_root (XNp_base);
   xs_stack . v_set_root (XNp_base);
   XEp_context = NULL;
   o_is_context_by_name = false;
   XNp_base_parent = NULL;
}

/// Compute an XPath expression, and return the number of nodes in the resulting node_ set.
/// \n Returns 0 if the result is not a node_ set
unsigned xpath_processor::u_compute_xpath_node_set ()
{
   er_compute_xpath ();
   if (er_result . e_type != e_node_set)
      return 0;
   return er_result . nsp_get_node_set () -> u_get_nb_node_in_set ();
}

/// Get one of the XML nodes from the resulting node_ set. Can only be used after a call to u_compute_xpath_node_set
void xpath_processor::v_get_xpath_base (
   unsigned u_order,             ///< Order of the node_. Must be between 0 and the number of nodes - 1
   const base * & XBp_res,  ///< Output node_
   bool & o_attrib)              ///< True if the output node_ is an attribute_, false if it's a node
{
   XBp_res = NULL;
   o_attrib = false;
   if (er_result . e_type != e_node_set)
      return;
   if (u_order >= er_result . nsp_get_node_set () -> u_get_nb_node_in_set ())
      return;
   XBp_res = er_result . nsp_get_node_set () -> XBp_get_base_in_set (u_order);
   o_attrib = er_result . nsp_get_node_set () -> o_is_attrib (u_order);
}

/// Retrieves an XPath node_ from the node_ set. This assumes you know it's not an attribute_
node * xpath_processor::XNp_get_xpath_node (
   unsigned u_order)    ///< Order of the node_. Must be between 0 and the number of nodes - 1
{
   bool o_attrib;
   const base * XBp_res;

   o_attrib = false;
   XBp_res = NULL;
   v_get_xpath_base (u_order, XBp_res, o_attrib);
   if (o_attrib)
      return NULL;
   return (node *) XBp_res;
}

/// Retrieves an XPath attribute_ from the node_ set. This assumes you know it's an attribute_
attribute * xpath_processor::XAp_get_xpath_attribute (
   unsigned u_order)    ///< Order of the node_. Must be between 0 and the number of nodes - 1
{
   bool o_attrib;
   const base * XBp_res;

   o_attrib = false;
   XBp_res = NULL;
   v_get_xpath_base (u_order, XBp_res, o_attrib);
   if (! o_attrib)
      return NULL;
   return (attribute *) XBp_res;
}

void xpath_processor::v_build_root ()
{
   if (XNp_base)
   {
      XNp_base_parent = XNp_base -> parent ();
      if (! XNp_base_parent)
         // no_ correct initialization of the xpath_processor object
         throw execution_error (1);
      // set the main node_ as the context one, if it's an element_
      if (XNp_base -> to_element ())
         XEp_context = XNp_base -> to_element ();
   }
   else
      XNp_base_parent = NULL;
}

/// Compute an XPath expression 
expression_result xpath_processor::er_compute_xpath ()
{
   try
   {
      XNp_base_parent = XNp_base -> parent ();
      if (! XNp_base_parent)
         // no_ correct initialization of the xpath_processor object
         throw execution_error (1);
      // set the main node_ as the context one, if it's an element_
      if (XNp_base -> to_element ())
         XEp_context = XNp_base -> to_element ();

      // Decode XPath expression
      v_evaluate ();

      // Compute result
      v_execute_stack ();

      /// The executions stack need to contain 1 and only 1 element_, otherwize it's not valid
      if (xs_stack . u_get_size () == 1)
      {
         er_result = * xs_stack . erp_top ();
         xs_stack . v_pop ();
         e_error = e_no_error;
      }
      else
      {
         expression_result er_null (NULL);
         er_result = er_null;
         e_error = e_error_stack;
      }
   }
   catch (syntax_error)
   {
      expression_result er_null (NULL);
      er_result = er_null;
      e_error = e_error_syntax;
   }
   catch (syntax_overflow)
   {
      expression_result er_null (NULL);
      er_result = er_null;
      e_error = e_error_overflow;
   }
   catch (execution_error)
   {
      expression_result er_null (NULL);
      er_result = er_null;
      e_error = e_error_execution;
   }

   return er_result;
}

/// Compute an XPath expression and return the result as a string
TIXML_STRING xpath_processor::S_compute_xpath ()
{
   expression_result er_res (XNp_base);
   TIXML_STRING S_res;

   er_res = er_compute_xpath ();
   S_res = er_res . S_get_string ();   
   return S_res;
}

/// Compute an XPath expression and return the result as an integer
int xpath_processor::i_compute_xpath ()
{
   expression_result er_res (XNp_base);
   int i_res;

   er_res = er_compute_xpath ();
   i_res = er_res . i_get_int ();   
   return i_res;
}

bool xpath_processor::o_compute_xpath ()
{
   expression_result er_res (XNp_base);
   bool o_res;

   er_res = er_compute_xpath ();
   o_res = er_res . o_get_bool ();   
   return o_res;
}

double xpath_processor::d_compute_xpath ()
{
   expression_result er_res (XNp_base);
   double d_res;

   er_res = er_compute_xpath ();
   d_res = er_res . d_get_double ();   
   return d_res;
}

/// Callback from the XPath decoder : a rule has to be applied
void xpath_processor::v_action (
	xpath_construct xc_rule,      ///< XPath Rule 
	unsigned u_sub,               ///< Rule sub number
	unsigned u_variable,          ///< Parameter, depends on the rule
	const char * cp_literal)      ///< Input literal, depends on the rule
{
   as_action_store . v_add (xc_rule, u_sub, u_variable, cp_literal);
   #ifdef TINYXPATH_DEBUG
      printf ("Action %2d : %s (%d,%d,%s)\n", as_action_store . i_get_size () - 1, cp_disp_construct (xc_rule), u_sub, u_variable, cp_literal);
   #endif
}

/// Internal use. Retrieves the current action counter
int xpath_processor::i_get_action_counter ()
{
   // callback for current stack position
   return as_action_store . i_get_size ();
}

/// Internal use. Executes the XPath expression. The executions starts at the end of the as_action_store list
void xpath_processor::v_execute_stack () 
{
   as_action_store . v_set_position (as_action_store . i_get_size () - 1);
   v_execute_one (xpath_expr, false);
}

/// Retrieves one quadruplet from the action placeholder
void xpath_processor::v_pop_one_action (
   xpath_construct & xc_action,  ///< next rule on placeholder
   unsigned & u_sub,             ///< Sub rule  
   unsigned & u_ref,             ///< Rule optional parameter
   TIXML_STRING & S_literal)     ///< Rule optional string
{
   int i_1, i_2, i_3;

   as_action_store . v_get (as_action_store . i_get_position (), i_1, i_2, i_3, S_literal);
   xc_action = (xpath_construct) i_1;
   u_sub = i_2;
   u_ref = i_3;
   as_action_store . v_dec_position ();
}

/// Executes one XPath rule
void xpath_processor::v_execute_one (
   xpath_construct xc_rule,      ///< Rule number
   bool o_skip_only)             ///< True if we only need to skip rules and not act on the data stack
{
	xpath_construct xc_action;
	unsigned u_sub;      
	unsigned u_variable;
	TIXML_STRING S_literal;
   TIXML_STRING S_temp;
	TIXML_STRING S_name;
   expression_result ** erpp_arg;
   unsigned u_arg;
   bool o_error;

   v_pop_one_action (xc_action, u_sub, u_variable, S_literal);
   // verify it's the rule we were waiting for
   if (xc_action != xc_rule)
      throw execution_error (2);
   switch (xc_action)
   {
      case xpath_expr :
         // [14] Expr ::= OrExpr 
         v_execute_one (xpath_or_expr, o_skip_only);
         break;

      case xpath_or_expr : 
         switch (u_sub)
         {
            case xpath_or_expr_simple :
               v_execute_one (xpath_and_expr, o_skip_only);
               break;
            case xpath_or_expr_or :
               o_error = false;
               erpp_arg = NULL;
               try
               {
                  v_execute_one (xpath_and_expr, o_skip_only);
                  if (! o_skip_only)
                  {
                     erpp_arg = new expression_result * [2];
                     memset (erpp_arg, 0, 2 * sizeof (expression_result *));
                     erpp_arg [1] = new expression_result (* xs_stack . erp_top ());
                     xs_stack . v_pop ();
                  }
                  v_execute_one (xpath_and_expr, o_skip_only); 
                  if (! o_skip_only)
                  {
                     erpp_arg [0] = new expression_result (* xs_stack . erp_top ());
                     xs_stack . v_pop ();
                     v_function_or (erpp_arg);
                  }
               }
               catch (execution_error)
               {
                  o_error = true;
               }
               if (erpp_arg)
               {
                  for (u_arg = 0; u_arg < 2; u_arg++)
                  {
                     if (erpp_arg [u_arg])
                        delete erpp_arg [u_arg];
                  }
                  delete [] erpp_arg;
               }
               if (o_error)
                  throw execution_error (3);
               break;
	         case xpath_or_expr_more :
	         {
		         // These  case is  involved for expressions like a or b or c
		         try
		         {
			         o_error = false;
			         erpp_arg = NULL;
			         v_execute_one (xpath_and_expr, o_skip_only);
			         if (! o_skip_only)
			         {
				         erpp_arg = new expression_result * [2];
				         memset (erpp_arg, 0, 2 * sizeof (expression_result *));
				         erpp_arg [1] = new expression_result (* xs_stack . erp_top ());
				         xs_stack . v_pop ();
			         }
			         v_execute_one (xpath_or_expr, o_skip_only);
			         if (! o_skip_only)
			         {
				         erpp_arg [0] = new expression_result (* xs_stack . erp_top ());
				         xs_stack . v_pop ();
				         v_function_or (erpp_arg);
			         }
		         }
		         catch (execution_error)
		         {
			         o_error = true;
		         }
		         if (erpp_arg)
		         {
			         for (u_arg = 0; u_arg < 2; u_arg++)
			         {
				         if (erpp_arg [u_arg])
					         delete erpp_arg [u_arg];
			         }
			         delete [] erpp_arg;
		         }
		         if (o_error)
			         throw execution_error (7);
	         }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -