PHP Conference Nagoya 2025

xml_parse

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

xml_parseBir XML belgeyi çözümler

Açıklama

xml_parse(XMLParser $çözümleyici, string $veri, bool $son = false): int

xml_parse() işlevi bir XML belgeyi çözümler. Yapılandırılmış olaylar için tanımlanmış eylemci işlevler gerektiği yerlerde defalarca çağrılabilir.

Bağımsız Değişkenler

çözümleyici

XMLParser nesnesi.

veri

Çözümlenecek veri parçası. Bir belge, çeşitli parçalara bölünerek bu parçalar xml_parse() işleviyle işlenerek çok sayıda adımda çözümlenebilir. Son parça çözümleneceği zaman son bağımsız değişkenine true atanmalıdır.

son

true belirtilirse, çözümleyiciye aktarılan veri son veri olarak ele alınır.

Dönen Değerler

Başarı durumunda 1, aksi takdirde 0 döndürür.

Başarısız bir çözümlemede hata bilgisi xml_get_error_code(), xml_error_string(), xml_get_current_line_number(), xml_get_current_column_number() ve xml_get_current_byte_index() işlevleri ile alınabilir.

Bilginize:

Öğe hataları gibi bazı hatalar sadece son bağımsız değişkenine true atandığı takdirde veri sonunda raporlanır.

Sürüm Bilgisi

Sürüm: Açıklama
8.0.0 ayrıştırıcı artık bir XMLParser örneği olabiliyor; evvelce resource türünde geçerli bir xml değeri kabul ederdi.

Örnekler

Örnek 1 - Büyük bir XML belgenin bölümlerine çözümlenmesi

Bu örnekte, tüm belgenin bellekte tutulmasına gerek kalmaması için büyük XML belgelerin bölümler halinde nasıl okunabileceği ve çözümlenebileceği gösterilmiştir. Kısa olması için hata işleme atlanmıştır.

<?php
$stream
= fopen('large.xml', 'r');
$parser = xml_parser_create();
// işleyici burada
while (($data = fread($stream, 16384))) {
xml_parse($parser, $data); // geçerli bölümü çözümle
}
xml_parse($parser, '', true); // çözümlemeyi bitir
xml_parser_free($parser);
fclose($stream);
add a note

User Contributed Notes 2 notes

up
21
neoyahuu at yahoo dot com
16 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
15 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
To Top