PHP 8.6.0 Beta 1 is available for testing

xml_parse

(PHP 4, PHP 5, PHP 7, PHP 8)

xml_parseInicia el análisis de un documento XML

Descripción

function xml_parse(XMLParser $parser, string $data, bool $is_final = false ): int

xml_parse() analiza un documento XML. Los gestores para los eventos configurados son llamados tantas veces como sea necesario.

Parámetros

parser

Una referencia al analizador XML a utilizar.

data

Una parte de los datos a analizar. Un documento puede ser analizado por partes mediante llamadas sucesivas a xml_parse() con nuevos datos, siempre que el parámetro is_final esté definido como true cuando se analicen los últimos datos.

is_final

Si está definido y vale true , data será el último fragmento de datos enviado al analizador.

Valores devueltos

Devuelve 1 en caso de éxito o 0 en caso de fallo.

En caso de fallo en el análisis, la causa del error puede obtenerse mediante las funciones xml_get_error_code() , xml_error_string() , xml_get_current_line_number() , xml_get_current_column_number() y xml_get_current_byte_index() .

Nota:

Algunos errores (incluyendo errores de entidades) son reportados al final de los datos, esto únicamente si is_final vale true .

Historial de cambios

Versión Descripción
8.0.0 parser ahora espera una instancia de XMLParser ; anteriormente, se esperaba un recurso xml de tipo resource válido.

Ejemplos

Ejemplo #1 Análisis de documentos XML grandes por partes

Este ejemplo muestra cómo los documentos XML grandes pueden ser leídos y analizados por partes, permitiendo así no mantener en memoria la totalidad del documento. No se ha establecido ningún gestor de errores para hacer el ejemplo más conciso.

<?php
$stream = fopen('examples/book-simple.xml', 'r');
$parser = xml_parser_create();
xml_set_element_handler(
 $parser,
 function($parser, $name, $attributes) { echo $name, PHP_EOL; },
 function($parser, $name) { echo $name, PHP_EOL; }
);
while (($data = fread($stream, 16384))) {
 xml_parse($parser, $data); // análisis de la parte actual
}
xml_parse($parser, '', true); // finalización del análisis
fclose($stream);

Found A Problem?

Learn How To Improve This PageSubmit a Pull RequestReport a Bug
+add a note

User Contributed Notes 2 notes

up
20
neoyahuu at yahoo dot com
18 years ago
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.
<?php
class xx_xml {
 // 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));
 }
 function error($msg) {
 echo "<div align=\"center\">
 <font color=\"red\"><b>Error: $msg</b></font>
 </div>";
 exit();
 }
}
?>

And example of retrieving XML data:
p/s: example use to retrieve weather
<?php
include_once "xx_xml.class.php";
// 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'] ;
?>

Hope this helps.
up
5
lz_speedy at web dot de
17 years ago
Best seen xml2array function ever
<?php
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
<root>
 <child1>
 <child1child1/>
 </child1>
</root>
create an array like 
array[root][child1][child1child1]
lg
+add a note

AltStyle によって変換されたページ (->オリジナル) /