xml_parse
xml_parse() разбирает XML-документ. Обработчики запрограммированных событий вызываются столько раз, сколько необходимо.
Список параметров
Ссылка на используемый XML-анализатор.
Часть данных для разбора. Документ можно разбирать по частям, вызывая функцию xml_parse() несколько раз с новыми данными, пока аргумент is_final не будет установлен в true , это сообщит анализатору, что разбирается последняя часть документа.
Если задан и установлен в true , data считается последней частью в этом разборе.
Возвращаемые значения
Возвращает 1 при успешном завершении, 0 в противном случае.
Замечание:
Некоторые ошибки (такие как ошибки при разборе сущностей) выдаются в конце разбора и получить их можно только когда is_final установлен в true .
Список изменений
Версия | Описание |
---|---|
8.0.0 | Параметр parser ожидает экземпляр XMLParser ; ранее ожидался корректный xml ресурс ( resource ). |
Примеры
Пример #1 Разбор по частям больших XML-документов
Этот пример показывает, как большие XML-документы могут быть прочитаны и разобраны по частям, поэтому нет необходимости держать весь документ в памяти. Обработка ошибок опущена для краткости.
$stream = fopen ( ‘large.xml’ , ‘r’ );
$parser = xml_parser_create ();
// установить обработчики
while (( $data = fread ( $stream , 16384 ))) xml_parse ( $parser , $data ); // разобрать текущую часть
>
xml_parse ( $parser , » , true ); // завершить разбор
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]
PHP SimpleXML Parser
SimpleXML is a PHP extension that allows us to easily manipulate and get XML data.
The SimpleXML Parser
SimpleXML is a tree-based parser.
SimpleXML provides an easy way of getting an element’s name, attributes and textual content if you know the XML document’s structure or layout.
SimpleXML turns an XML document into a data structure you can iterate through like a collection of arrays and objects.
Compared to DOM or the Expat parser, SimpleXML takes a fewer lines of code to read text data from an element.
Installation
From PHP 5, the SimpleXML functions are part of the PHP core. No installation is required to use these functions.
PHP SimpleXML — Read From String
The PHP simplexml_load_string() function is used to read XML data from a string.
Assume we have a variable that contains XML data, like this:
The example below shows how to use the simplexml_load_string() function to read XML data from a string:
Example
$xml=simplexml_load_string($myXMLData) or die(«Error: Cannot create object»);
print_r($xml);
?>
The output of the code above will be:
SimpleXMLElement Object ( [to] => Tove [from] => Jani [heading] => Reminder [body] => Don’t forget me this weekend! )
Error Handling Tip: Use the libxml functionality to retrieve all XML errors when loading the document and then iterate over the errors. The following example tries to load a broken XML string:
Example
$xml = simplexml_load_string($myXMLData);
if ($xml === false) echo «Failed loading XML: «;
foreach(libxml_get_errors() as $error) echo «
«, $error->message;
>
> else print_r($xml);
>
?>
The output of the code above will be:
Failed loading XML:
Opening and ending tag mismatch: user line 3 and wronguser
Opening and ending tag mismatch: email line 4 and wrongemail
PHP SimpleXML — Read From File
The PHP simplexml_load_file() function is used to read XML data from a file.
Assume we have an XML file called «note.xml», that looks like this:
The example below shows how to use the simplexml_load_file() function to read XML data from a file:
Example
The output of the code above will be:
SimpleXMLElement Object ( [to] => Tove [from] => Jani [heading] => Reminder [body] => Don’t forget me this weekend! )
Tip: The next chapter shows how to get/retrieve node values from an XML file with SimpleXML!
More PHP SimpleXML
For more information about the PHP SimpleXML functions, visit our PHP SimpleXML Reference.