PHP 8.5.8 Released!

xml_parse

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

xml_parse开始解析 XML 文档

说明

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

xml_parse() 解析 XML 文档。已配置事件的处理程序根据需要被无限次调用。

参数

parser

指向将要使用的 XML 解析器的指针。

data

要解析的数据块。可以通过使用新数据多次调用 xml_parse() 来分段解析文档,只要在解析最后一个数据时设置 is_final 参数且为 true 即可。

is_final

如果被设置为 true ,则 data 为当前解析中最后一段数据。

返回值

成功时返回 1,失败时返回 0。

若解析失败,可以使用如下函数获取错误信息:xml_get_error_code() xml_error_string() xml_get_current_line_number() xml_get_current_column_number() xml_get_current_byte_index()

注意:

is_final 参数设置为 true ,一些错误(例如 entity 错误)将会在数据末尾报告。

更新日志

版本 说明
8.0.0 parser 现在接受 XMLParser 实例;之前接受有效的 xml resource

示例

示例 #1 分块解析大型 XML 文档

此示例展示了如何以块的形式读取和解析大型 XML 文档,这样就不必将整个文档保存在内存中。为简洁起见,省略了错误处理。

<?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); // parse the current chunk
}
xml_parse($parser, '', true); // finalize parsing
fclose($stream);

发现了问题?

了解如何改进此页面提交拉取请求报告一个错误
+添加备注

用户贡献的备注 2 notes

up
18
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
+添加备注

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