xml_parse
xml_parse() parses an XML document. The handlers for the configured events are called as many times as necessary.
Parameters
A reference to the XML parser to use.
Chunk of data to parse. A document may be parsed piece-wise by calling xml_parse() several times with new data, as long as the is_final parameter is set and true when the last data is parsed.
If set and true , data is the last piece of data sent in this parse.
Return Values
Returns 1 on success or 0 on failure.
Note:
Some errors (such as entity errors) are reported at the end of the data, thus only if is_final is set and true .
Changelog
Version | Description |
---|---|
8.0.0 | parser expects an XMLParser instance now; previously, a valid xml resource was expected. |
Examples
Example #1 Chunked parsing of large XML documents
This example shows how large XML documents can be read and parsed in chunks, so that it not necessary to keep the whole document in memory. Error handling is omitted for brevity.
$stream = fopen ( ‘large.xml’ , ‘r’ );
$parser = xml_parser_create ();
// set up the handlers here
while (( $data = fread ( $stream , 16384 ))) xml_parse ( $parser , $data ); // parse the current chunk
>
xml_parse ( $parser , » , true ); // finalize parsing
xml_parser_free ( $parser );
fclose ( $stream );?php
User Contributed Notes 19 notes
Instead of passing a URL, we can pass the XML content to this class (either you
want to use CURL, Socks or fopen to retrieve it first) and instead of using
array, I’m using separator ‘|’ to identify which data to get (in order to make
it short to retrieve a complex XML data). Here is my class with built-in fopen
which you can pass URL or you can pass the content instead :
p/s : thanks to this great help page.
// XML parser variables
var $parser ;
var $name ;
var $attr ;
var $data = array();
var $stack = array();
var $keys ;
var $path ;
// either you pass url atau contents.
// Use ‘url’ or ‘contents’ for the parameter
var $type ;
// function with the default parameter value
function xx_xml ( $url = ‘http://www.example.com’ , $type = ‘url’ ) <
$this -> type = $type ;
$this -> url = $url ;
$this -> parse ();
>
// parse XML data
function parse ()
<
$data = » ;
$this -> parser = xml_parser_create ();
xml_set_object ( $this -> parser , $this );
xml_set_element_handler ( $this -> parser , ‘startXML’ , ‘endXML’ );
xml_set_character_data_handler ( $this -> parser , ‘charXML’ );
xml_parser_set_option ( $this -> parser , XML_OPTION_CASE_FOLDING , false );
if ( $this -> type == ‘url’ ) <
// if use type = ‘url’ now we open the XML with fopen
if (!( $fp = @ fopen ( $this -> url , ‘rb’ ))) <
$this -> error ( «Cannot open < $this ->url > » );
>
while (( $data = fread ( $fp , 8192 ))) <
if (! xml_parse ( $this -> parser , $data , feof ( $fp ))) <
$this -> error ( sprintf ( ‘XML error at line %d column %d’ ,
xml_get_current_line_number ( $this -> parser ),
xml_get_current_column_number ( $this -> parser )));
>
>
> else if ( $this -> type == ‘contents’ ) <
// Now we can pass the contents, maybe if you want
// to use CURL, SOCK or other method.
$lines = explode ( «\n» , $this -> url );
foreach ( $lines as $val ) <
if ( trim ( $val ) == » )
continue;
$data = $val . «\n» ;
if (! xml_parse ( $this -> parser , $data )) <
$this -> error ( sprintf ( ‘XML error at line %d column %d’ ,
xml_get_current_line_number ( $this -> parser ),
xml_get_current_column_number ( $this -> parser )));
>
>
>
>
function startXML ( $parser , $name , $attr ) <
$this -> stack [ $name ] = array();
$keys = » ;
$total = count ( $this -> stack )- 1 ;
$i = 0 ;
foreach ( $this -> stack as $key => $val ) <
if ( count ( $this -> stack ) > 1 ) <
if ( $total == $i )
$keys .= $key ;
else
$keys .= $key . ‘|’ ; // The saparator
>
else
$keys .= $key ;
$i ++;
>
if ( array_key_exists ( $keys , $this -> data )) <
$this -> data [ $keys ][] = $attr ;
> else
$this -> data [ $keys ] = $attr ;
$this -> keys = $keys ;
>
function endXML ( $parser , $name ) <
end ( $this -> stack );
if ( key ( $this -> stack ) == $name )
array_pop ( $this -> stack );
>
function charXML ( $parser , $data ) <
if ( trim ( $data ) != » )
$this -> data [ $this -> keys ][ ‘data’ ][] = trim ( str_replace ( «\n» , » , $data ));
>
?>
And example of retrieving XML data:
p/s: example use to retrieve weather
// Im using simple curl (the original is in class) to get the contents
$pageurl = «http://xml.weather.yahoo.com/forecastrss?p=MYXX0008&u=c» ;
curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , 1 );
curl_setopt ( $ch , CURLOPT_URL , $pageurl );
$thecontents = curl_exec ( $ch );
curl_close ( $ch );
// We want to pass only a ready XML content instead of URL
// But if you want to use URL , skip the curl functions above and use this
// $xx4 = new xx_xml(«url here»,’url’);
$xx4 = new xx_xml ( $thecontents , ‘contents’ );
// As you can see, we use saparator ‘|’ instead of long array
$Code = $xx4 -> data [ ‘rss|channel|item|yweather:condition’ ][ ‘code’ ] ;
$Celcius = $xx4 -> data [ ‘rss|channel|item|yweather:condition’ ][ ‘temp’ ] ;
$Text = $xx4 -> data [ ‘rss|channel|item|yweather:condition’ ][ ‘text’ ] ;
$Cityname = $xx4 -> data [ ‘rss|channel|yweather:location’ ][ ‘city’ ] ;
Best seen xml2array function ever
function xml2array ( $url , $get_attributes = 1 , $priority = ‘tag’ )
$contents = «» ;
if (! function_exists ( ‘xml_parser_create’ ))
return array ();
>
$parser = xml_parser_create ( » );
if (!( $fp = @ fopen ( $url , ‘rb’ )))
return array ();
>
while (! feof ( $fp ))
$contents .= fread ( $fp , 8192 );
>
fclose ( $fp );
xml_parser_set_option ( $parser , XML_OPTION_TARGET_ENCODING , «UTF-8» );
xml_parser_set_option ( $parser , XML_OPTION_CASE_FOLDING , 0 );
xml_parser_set_option ( $parser , XML_OPTION_SKIP_WHITE , 1 );
xml_parse_into_struct ( $parser , trim ( $contents ), $xml_values );
xml_parser_free ( $parser );
if (! $xml_values )
return; //Hmm.
$xml_array = array ();
$parents = array ();
$opened_tags = array ();
$arr = array ();
$current = & $xml_array ;
$repeated_tag_index = array ();
foreach ( $xml_values as $data )
unset ( $attributes , $value );
extract ( $data );
$result = array ();
$attributes_data = array ();
if (isset ( $value ))
if ( $priority == ‘tag’ )
$result = $value ;
else
$result [ ‘value’ ] = $value ;
>
if (isset ( $attributes ) and $get_attributes )
foreach ( $attributes as $attr => $val )
if ( $priority == ‘tag’ )
$attributes_data [ $attr ] = $val ;
else
$result [ ‘attr’ ][ $attr ] = $val ; //Set all the attributes in a array called ‘attr’
>
>
if ( $type == «open» )
<
$parent [ $level — 1 ] = & $current ;
if (! is_array ( $current ) or (! in_array ( $tag , array_keys ( $current ))))
$current [ $tag ] = $result ;
if ( $attributes_data )
$current [ $tag . ‘_attr’ ] = $attributes_data ;
$repeated_tag_index [ $tag . ‘_’ . $level ] = 1 ;
$current = & $current [ $tag ];
>
else
if (isset ( $current [ $tag ][ 0 ]))
$current [ $tag ][ $repeated_tag_index [ $tag . ‘_’ . $level ]] = $result ;
$repeated_tag_index [ $tag . ‘_’ . $level ]++;
>
else
<
$current [ $tag ] = array (
$current [ $tag ],
$result
);
$repeated_tag_index [ $tag . ‘_’ . $level ] = 2 ;
if (isset ( $current [ $tag . ‘_attr’ ]))
$current [ $tag ][ ‘0_attr’ ] = $current [ $tag . ‘_attr’ ];
unset ( $current [ $tag . ‘_attr’ ]);
>
>
$last_item_index = $repeated_tag_index [ $tag . ‘_’ . $level ] — 1 ;
$current = & $current [ $tag ][ $last_item_index ];
>
>
elseif ( $type == «complete» )
if (!isset ( $current [ $tag ]))
$current [ $tag ] = $result ;
$repeated_tag_index [ $tag . ‘_’ . $level ] = 1 ;
if ( $priority == ‘tag’ and $attributes_data )
$current [ $tag . ‘_attr’ ] = $attributes_data ;
>
else
if (isset ( $current [ $tag ][ 0 ]) and is_array ( $current [ $tag ]))
$current [ $tag ][ $repeated_tag_index [ $tag . ‘_’ . $level ]] = $result ;
if ( $priority == ‘tag’ and $get_attributes and $attributes_data )
$current [ $tag ][ $repeated_tag_index [ $tag . ‘_’ . $level ] . ‘_attr’ ] = $attributes_data ;
>
$repeated_tag_index [ $tag . ‘_’ . $level ]++;
>
else
$current [ $tag ] = array (
$current [ $tag ],
$result
);
$repeated_tag_index [ $tag . ‘_’ . $level ] = 1 ;
if ( $priority == ‘tag’ and $get_attributes )
if (isset ( $current [ $tag . ‘_attr’ ]))
<
$current [ $tag ][ ‘0_attr’ ] = $current [ $tag . ‘_attr’ ];
unset ( $current [ $tag . ‘_attr’ ]);
>
if ( $attributes_data )
$current [ $tag ][ $repeated_tag_index [ $tag . ‘_’ . $level ] . ‘_attr’ ] = $attributes_data ;
>
>
$repeated_tag_index [ $tag . ‘_’ . $level ]++; //0 and 1 index is already taken
>
>
>
elseif ( $type == ‘close’ )
$current = & $parent [ $level — 1 ];
>
>
return ( $xml_array );
>
?>
Returns a well formed array like the structure of the xml-document
create an array like
array[root][child1][child1child1]