xlink:href, logourl(format,onlineresource) * style: name, title, legendurl(format,onlineresource->xlink:href) */ class CapabilitiesParser { var $parser; var $version = NULL; // wms version var $root = NULL; // root element name (depends on wms version) var $path = ''; // current path (excluding root) var $layers = array(); var $layer_level = 0; var $layer_props; var $inAttribution = false; var $inStyle = false; var $inMetadata = false; var $element = ''; // current element var $cbLayer = NULL; var $cbLayerParams = NULL; var $numLayers = 0; function CapabilitiesParser( ) { $this->parser = xml_parser_create( "UTF-8" ); xml_parser_set_option( $this->parser, XML_OPTION_CASE_FOLDING, 0 ); xml_set_element_handler( $this->parser, array(&$this,"_startElement"), array(&$this,"_endElement") ); xml_set_character_data_handler( $this->parser, array(&$this,"_characterData") ); $this->layer_level = 0; $this->layer_props = array(); $this->layer_props[ $this->layer_level ] = array( ); $this->layers = array( ); } function free_parser( ) { xml_parser_free( $this->parser ); } function inSomething() { return $this->inAttribution || $this->inStyle !== false; } function parse( $capabilities, $cbLayer = NULL, $cbLayerParams = NULL ) { $this->cbLayer = $cbLayer; $this->cbLayerParams = $cbLayerParams; return xml_parse( $this->parser, $capabilities, TRUE ); } function _startElement( $parser, $name, $attrs ) { //print '_startElement ' . $name . "\n"; if( ! $this->root ) { $this->root = $name; $this->version = $attrs['version']; $this->layer_props[ $this->layer_level ]['wms_version'] = $this->version; } else { $this->path .= '/' . $name; } $this->element = $name; switch( $name ) { case 'Attribution': $this->inAttribution = true; break; case 'Style': $this->inStyle = true; // $this->layer_props[ $this->layer_level ]['Style'] = array( ); break; case 'MetadataURL': $this->inMetadata = true; break; case 'OnlineResource': if( $this->inStyle !== false ) { $this->layer_props[ $this->layer_level ]['Style'][ $this->inStyle ] = $attrs['xlink:href']; break; } if( $this->inMetadata !== false ) { $this->layer_props[ $this->layer_level ]['MetadataURL'] = $attrs['xlink:href']; } break; case 'Layer': // the previous layer is a parent layer of the new one if( ! isset($this->layer_props[ $this->layer_level ]['layer_id']) ) { $this->layer_props[ $this->layer_level ]['layer_id'] = $this->numLayers++; if( $this->cbLayer ) eval( $this->cbLayer . "(\$this->layer_props[\$this->layer_level], \$this->cbLayerParams );" ); else { // print $this->layer_level . ' : ' . var_export($this->layer_props[ $this->layer_level ],true) . '
'; $this->layers[] = $this->layer_props[ $this->layer_level ]; } } else { // adjust layer of $this->layer_props[ $this->layer_level ] // count child layers? } $this->layer_level += 1; // copy layer_props for new layer level and merge new attrs // @todo: merge only inherited props! $inherited_values = array(); $inherited_properties = array( 'Style', 'SRS', 'LatLonBoundingBox', 'BoundingBox', 'queryable', 'opaque', 'cascaded' ); foreach( $inherited_properties as $prop ) { if( isset($this->layer_props[ $this->layer_level - 1 ][$prop]) ) $inherited_values[$prop] = $this->layer_props[ $this->layer_level - 1 ][$prop]; } $this->layer_props[ $this->layer_level ] = array_merge( $inherited_values, $attrs ); // print var_export( array($name,$attrs,$this->layer_level), true ) . '
'; break; case 'LatLonBoundingBox'; if( $this->layer_level > 0 ) $this->layer_props[ $this->layer_level][ $name ] = $attrs; break; case 'BoundingBox': if( $this->layer_level > 0 ) { if( ! isset($this->layer_props[ $this->layer_level][ $name ]) ) $this->layer_props[ $this->layer_level][ $name ] = array(); $SRS = $attrs['SRS']; unset( $attrs['SRS'] ); $this->layer_props[ $this->layer_level][ $name ][$SRS] = $attrs; } break; default: // print $this->path . ':' . var_export($attrs,true) . '
'; break; } // print $this->path . ': attrs = ' . var_export($attrs,true) . '
'; } function _characterData( $parser, $data ) { //print '_characterData ' . $this->element . ':' . $data . "\n"; if( $this->element != '' ) { $text = trim($data); if( $this->layer_level == 0 ) { switch( $this->element ) { case 'Title': case 'Name': case 'Abstract': //print 'abstract=' . $test . '
'; $this->layer_props[ $this->layer_level][ $this->element ] .= $text; break; } } if( $this->layer_level > 0 && ! $this->inSomething() ) { switch( $this->element ) { case 'Title': case 'Name': // if not a style name!! $this->layer_props[ $this->layer_level][ $this->element ] .= $text; break; case 'Abstract': //print 'abstract=' . $test . '
'; // if not a style name!! $this->layer_props[ $this->layer_level][ $this->element ] .= $text; break; case 'SRS': if( isset($this->layer_props[ $this->layer_level][ $this->element ]) && $this->layer_props[ $this->layer_level][ $this->element ] != '' ) { $this->layer_props[ $this->layer_level][ $this->element ] .= ' '; } $this->layer_props[ $this->layer_level][ $this->element ] .= $text; break; } } else if( $this->inStyle !== false ) { switch( $this->element ) { case 'Name': $this->inStyle .= $text; break; } } // print $this->path . ':' . $this->element . '=' . $text . '|
'; // print '---> ' . $this->layer_level . '/' . var_export($this->layer_props[ $this->layer_level],true) . '
'; //$this->element = ''; // previously here instead of at start of _endElement } } function _endElement( $parser, $name ) { //print '_endElement ' . $name . "\n"; $this->element = ''; // instead of at end of _characterData function $this->path = substr( $this->path, 0, -(1+strlen($name)) ); switch( $name ) { case 'Layer': if( ! $this->layer_props[ $this->layer_level ]['layer_id'] ) { $this->layer_props[ $this->layer_level ]['layer_id'] = $this->numLayers++; if( $this->cbLayer ) eval( $this->cbLayer . "(\$this->layer_props[\$this->layer_level], \$this->cbLayerParams );" ); else { // print $this->layer_level . ' : ' . var_export($this->layer_props[ $this->layer_level ],true) . '
'; $this->layers[] = $this->layer_props[ $this->layer_level ]; } } $this->layer_level -= 1; array_pop( $this->layer_props ); break; case 'Attribution': $this->inAttribution = false; break; case 'Style': $this->inStyle = false; break; case 'Metadata': $this->inMetadata = false; break; default: break; } } } // CapabilitiesParser ?>