xml_parse

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

xml_parse开始解析 XML 文档

描述

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 时才会报告。

变更日志

版本 描述
8.0.0 parser 现在期望一个 XMLParser 实例;之前,期望一个有效的 xml resource

范例

示例 #1 大 XML 文档的逐块解析

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

<?php
$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);
添加笔记

用户贡献笔记 2 notes

up
21
neoyahuu at yahoo dot com
16 年前
我们可以传递 XML 内容而不是 URL 到此类(无论您是
希望首先使用 CURL、Socks 或 fopen 来检索它),并且不使用
数组,我使用分隔符 '|' 来标识要获取哪些数据(以便
检索复杂的 XML 数据时保持简短)。这是我的类,它内置了 fopen
可以传递 URL 也可以传递内容

p/s:感谢这个很棒的帮助页面。

<?php

class xx_xml {

// XML 解析器变量
var $parser;
var
$name;
var
$attr;
var
$data = array();
var
$stack = array();
var
$keys;
var
$path;

// 传入 URL 或 内容。
// 使用 'url' 或 'contents' 作为参数
var $type;

// 带有默认参数值的函数
function xx_xml($url='http://www.example.com', $type='url') {
$this->type = $type;
$this->url = $url;
$this->parse();
}

// 解析 XML 数据
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') {
// 如果使用类型为 'url',现在使用 fopen 打开 XML

if (!($fp = @fopen($this->url, 'rb'))) {
$this->error("无法打开 {$this->url}");
}

while ((
$data = fread($fp, 8192))) {
if (!
xml_parse($this->parser, $data, feof($fp))) {
$this->error(sprintf('XML 错误发生在第 %d 行,第 %d 列',
xml_get_current_line_number($this->parser),
xml_get_current_column_number($this->parser)));
}
}
} else if (
$this->type == 'contents') {
// 现在可以传入内容,也许你想要
// 使用 CURL、SOCK 或其他方法。
$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 错误发生在第 %d 行,第 %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 . '|'; // 分隔符
}
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>错误:
$msg</b></font>
</div>"
;
exit();
}
}

?>

获取 XML 数据的示例
p/s: 获取天气的示例

<?php
include_once "xx_xml.class.php";

// 我使用简单的 curl(原始代码在类中)来获取内容

$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);

// 我们只想要传递一个准备好的 XML 内容,而不是 URL
// 但是如果你想使用 URL,请跳过上面的 curl 函数并使用以下代码
// $xx4 = new xx_xml("url here",'url');

$xx4 = new xx_xml($thecontents,'contents');
// 正如你所看到的,我们使用分隔符 '|' 代替长数组
$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'] ;

?>

希望这能帮到你。
up
5
lz_speedy at web dot de
15 年前
有史以来最好的 xml2array 函数
<?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);
}
?>

返回一个与 xml 文档结构一致的格式良好的数组

<root>
<child1>
<child1child1/>
</child1>
</root>

创建一个类似的数组
array[root][child1][child1child1]

lg
To Top