Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

xml_event_parser.php

Go to the documentation of this file.
00001 
00002 /** @file xml_event_parser.php
00003 * Definition of class xml_event_parser.
00004 */
00005 #include "error_logger.php"
00006 /**
00007 * Event-based parsing of xml data.
00008 * This class provides interface for event-based processing
00009 * of xml file with known structure.
00010 *
00011 * Classes-owners should declare functions to process open elements,
00012 * close elements and CDATA inside elements.
00013 *
00014 * Open elements handlers should have name such:
00015 *   - xep_open_<element_name1>
00016 *   - xep_open_<elements_name2>_<element_name1>
00017 *   - xep_open_<elements_name3>_<element_name2>_<element_name1>             \n
00018 * and must have prototype such
00019 *   - void xep_open_element( attributes );                                 \n
00020 * where attributes is an array of attributes of element, just like expat
00021 * it gives.
00022 *
00023 * Close elements handlers should have name such:
00024 *   - xep_close_<element_name1>
00025 *   - xep_close_<elements_name2>_<element_name1>
00026 *   - xep_close_<elements_name3>_<element_name2>_<element_name1>            \n
00027 *  and must have prototype such
00028 *   - void xep_close_element();
00029 *
00030 * CDATA handlers should have name such:
00031 *   - xep_cdata_<element_name1>
00032 *   - xep_cdata_<elements_name2>_<element_name1>
00033 *   - xep_cdata_<elements_name3>_<element_name2>_<element_name1>            \n
00034 * and must have prototype such
00035 *   - void xep_cdata_element( cdata );                                     \n
00036 * where cdata is a string of trimed text inside element. Handler will not be
00037 * called if trimed string is empty.
00038 *
00039 * Case-folding is disabled. Short-name handlers called first.
00040 * For example, for                                            \n
00041 * <aa>                                                        \n
00042 *   <bb/>                                                     \n
00043 *    some text                                                \n
00044 * </aa>                                                       \n
00045 * Calls will be
00046 * xep_open_aa, xep_open_bb, xep_open_aa_bb, xep_close_bb, xep_close_aa_bb,
00047 * xep_cdata_aa, xep_close_aa
00048 */
00049 class xml_event_parser : public  error_logger
00050 {
00051 public:
00052   /** XML parser descriptor. */
00053   var xml_parser = 0;
00054   /** Parent elements. */
00055   var elements = array();
00056   /** Depth level. */
00057   var depth = 0;
00058   /** Class-owner. */
00059   var owner;
00060   /**
00061   * Constructor.
00062   * @param object owner - class-owner
00063   */
00064   function xml_event_parser( &owner )
00065   {
00066 public:
00067     this->owner = &owner;
00068   }
00069   /**
00070   * Parse data from string.
00071   * @param string data - xml data to parse.
00072   */
00073   function parse( data )
00074   {
00075     if( data == '' )
00076       return 0;
00077     else
00078     {
00079       this->elements = array();
00080       this->depth = 0;
00081       if( !this->xml_parser = xml_parser_create() )
00082         return this->err( "unable to create xml parser", "parse", __LINE__, __FILE__ );
00083       if( !xml_parser_set_option( this->xml_parser, XML_OPTION_CASE_FOLDING, 0 ) )
00084       {
00085         xml_parser_free( this->xml_parser );
00086         return this->err( "unable to disable case-folding", "parse", __LINE__, __FILE__ );
00087       }
00088       xml_set_object( this->xml_parser, this );
00089       if( !xml_set_element_handler( this->xml_parser, "tagxep_open", "tagxep_close" ) )
00090       {
00091         xml_parser_free( this->xml_parser );
00092         return this->err( "unable to set element handler", "parse", __LINE__, __FILE__ );
00093       }
00094       if( !xml_set_character_data_handler( this->xml_parser, "cdata" ) )
00095       {
00096         xml_parser_free( this->xml_parser );
00097         return this->err( "unable to set CDATA handler", "parse", __LINE__, __FILE__ );
00098       }
00099       if( !xml_parse( this->xml_parser, data, 1 ) )
00100       {
00101         this->err( "XML error: ".
00102           xml_error_string( xml_get_error_code( this->xml_parser ) ).
00103           " at line ".
00104           xml_get_current_line_number( this->xml_parser ), "parse", __LINE__, __FILE__ );
00105         xml_parser_free( this->xml_parser );
00106         return 0;
00107       }
00108       xml_parser_free( this->xml_parser );
00109       return 1;
00110     } //if( data == '' )
00111   }
00112   /**
00113   * Parse xml file.
00114   * @param string fname - name of xml file to parse
00115   */
00116   function parse_file( fname )
00117   {
00118     if( fname == '' )
00119       return this->err( "no filename specified", "parse_file", __LINE__, __FILE__ );
00120     else
00121     {
00122       this->elements = array();
00123       this->depth = 0;
00124       if( !this->xml_parser = xml_parser_create() )
00125         return this->err( "unable to create parser", "parse_file", __LINE__, __FILE__ );
00126       if( !xml_parser_set_option( this->xml_parser, XML_OPTION_CASE_FOLDING, 0 ) )
00127       {
00128         xml_parser_free( this->xml_parser );
00129         return this->err( "unable to disable case-folding", "parse_file", __LINE__, __FILE__ );
00130       }
00131       xml_set_object( this->xml_parser, this );
00132       if( !xml_set_element_handler( this->xml_parser, "tagxep_open", "tagxep_close" ) )
00133       {
00134         xml_parser_free( this->xml_parser );
00135         return this->err( "unable to set element handler", "parse_file", __LINE__, __FILE__ );
00136       }
00137       if( !xml_set_character_data_handler( this->xml_parser, "cdata" ) )
00138       {
00139         xml_parser_free( this->xml_parser );
00140         this->err( "unable to set CDATA handler", "parse_file", __LINE__, __FILE__ );
00141       }
00142       if( !( fp = fopen( fname, "r" ) ) )
00143       {
00144         xml_parser_free( this->xml_parser );
00145         return this->err( "unable to open file fname", "parse_file", __LINE__, __FILE__ );
00146       }
00147       while( fname = fread( fp, 65535 ) )
00148         if( !xml_parse( this->xml_parser, fname, feof( fp ) ) )
00149         {
00150           this->err( "XML error: ".
00151             xml_error_string( xml_get_error_code( this->xml_parser ) ).
00152             " at line ".
00153             xml_get_current_line_number( this->xml_parser ), "parse_file", __LINE__, __FILE__ );
00154           xml_parser_free( this->xml_parser );
00155           return 0;
00156         }
00157       xml_parser_free( this->xml_parser );
00158       return 1;
00159     } //if( fname == '' )
00160   }
00161   function tagxep_open( parser, tag, attributes )
00162   {
00163     this->elements[ this->depth ] = tag;
00164     this->depth++;
00165     path = '';
00166     for( i = this->depth - 1; i >= 0; i-- )
00167     {
00168       path = "_".this->elements[ i ].path;
00169       name = "xep_open".path;
00170       if( method_exists( this->owner, name ) )
00171         this->owner->name( attributes );
00172     }
00173   }
00174   function cdata( parser, cdata )
00175   {
00176     data = trim( cdata );
00177     if( data != '' )
00178     {
00179       path = '';
00180       for( i = this->depth - 1; i >= 0; i-- )
00181       {
00182         path = "_".this->elements[ i ].path;
00183         name = "xep_cdata".path;
00184         if( method_exists( this->owner, name ) )
00185           this->owner->name( cdata );
00186       }
00187     }
00188   }
00189   function tagxep_close( parser, tag )
00190   {
00191     path = '';
00192     for( i = this->depth - 1; i >= 0; i-- )
00193     {
00194       path = "_".this->elements[ i ].path;
00195       name = "xep_close".path;
00196       if( method_exists( this->owner, name ) )
00197         this->owner->name();
00198     }
00199     this->depth--;
00200     unset( this->elements[ this->depth ] );
00201   }
00202 }
00203 
00204 X-Powered-By: PHP/4.0.8-dev
00205 Content-type: text/html
00206 
00207 

Generated on Tue Mar 11 08:35:13 2003 for SES by doxygen1.2.16