filterMatch */ function __construct( $file, $filterCallback=null ) { $this->filterCallback = $filterCallback; $this->run( $file ); } /** * Get the root element. Simple accessor to $rootElement */ public function getRootElement() { return $this->rootElement; } private function run( $fname ) { $parser = xml_parser_create_ns( 'UTF-8' ); // case folding violates XML standard, turn it off xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false ); xml_set_element_handler( $parser, array( $this, 'rootElementOpen' ), false ); $file = fopen( $fname, "rb" ); do { $chunk = fread( $file, 32768 ); $ret = xml_parse( $parser, $chunk, feof( $file ) ); if( $ret == 0 ) { // XML isn't well-formed! fclose( $file ); xml_parser_free( $parser ); return; } } while( !feof( $file ) ); $this->wellFormed = true; fclose( $file ); xml_parser_free( $parser ); } private function rootElementOpen( $parser, $name, $attribs ) { $this->rootElement = $name; if( is_callable( $this->filterCallback ) ) { xml_set_element_handler( $parser, array( $this, 'elementOpen' ), false ); $this->elementOpen( $parser, $name, $attribs ); } else { // We only need the first open element xml_set_element_handler( $parser, false, false ); } } private function elementOpen( $parser, $name, $attribs ) { if( call_user_func( $this->filterCallback, $name, $attribs ) ) { // Filter hit! $this->filterMatch = true; } } }