fusionpbx/includes/phpsvnclient/xml_parser.php

427 lines
11 KiB
PHP

<?php
/*
* xml_parser.php
*
* @(#) $Header: /home/mlemos/cvsroot/xmlparser/xml_parser.php,v 1.19 2006/11/22 01:25:05 mlemos Exp $
*
*/
/*
* Parser error numbers:
*
* 1 - Could not create the XML parser
* 2 - Could not parse data
* 3 - Could not read from input stream
*
*/
$xml_parser_handlers=array();
Function xml_parser_start_element_handler($parser,$name,$attrs)
{
global $xml_parser_handlers;
if(!strcmp($xml_parser_handlers[$parser]->error,""))
$xml_parser_handlers[$parser]->StartElement($xml_parser_handlers[$parser],$name,$attrs);
}
Function xml_parser_end_element_handler($parser,$name)
{
global $xml_parser_handlers;
if(!strcmp($xml_parser_handlers[$parser]->error,""))
$xml_parser_handlers[$parser]->EndElement($xml_parser_handlers[$parser],$name);
}
Function xml_parser_character_data_handler($parser,$data)
{
global $xml_parser_handlers;
if(!strcmp($xml_parser_handlers[$parser]->error,""))
$xml_parser_handlers[$parser]->CharacterData($xml_parser_handlers[$parser],$data);
}
class xml_parser_handler_class
{
var $xml_parser;
var $error_number=0;
var $error="";
var $error_code=0;
var $error_line,$error_column,$error_byte_index;
var $structure=array();
var $positions=array();
var $path="";
var $store_positions=0;
var $simplified_xml=0;
var $fail_on_non_simplified_xml=0;
Function SetError(&$object,$error_number,$error)
{
$object->error_number=$error_number;
$object->error=$error;
$object->error_line=xml_get_current_line_number($object->xml_parser);
$object->error_column=xml_get_current_column_number($object->xml_parser);
$object->error_byte_index=xml_get_current_byte_index($object->xml_parser);
}
Function SetElementData(&$object,$path,&$data)
{
$object->structure[$path]=$data;
if($object->store_positions)
{
$object->positions[$path]=array(
"Line"=>xml_get_current_line_number($object->xml_parser),
"Column"=>xml_get_current_column_number($object->xml_parser),
"Byte"=>xml_get_current_byte_index($object->xml_parser)
);
}
}
Function StartElement(&$object,$name,&$attrs)
{
if(strcmp($this->path,""))
{
$element=$object->structure[$this->path]["Elements"];
$object->structure[$this->path]["Elements"]++;
$this->path.=",$element";
}
else
{
$element=0;
$this->path="0";
}
$data=array(
"Tag"=>$name,
"Elements"=>0
);
if($object->simplified_xml)
{
if($object->fail_on_non_simplified_xml
&& count($attrs)>0)
{
$this->SetError($object,2,"Simplified XML can not have attributes in tags");
return;
}
}
else
$data["Attributes"]=$attrs;
$this->SetElementData($object,$this->path,$data);
}
Function EndElement(&$object,$name)
{
$this->path=(($position=strrpos($this->path,",")) ? substr($this->path,0,$position) : "");
}
Function CharacterData(&$object,$data)
{
$element=$object->structure[$this->path]["Elements"];
$previous=$this->path.",".strval($element-1);
if($element>0
&& GetType($object->structure[$previous])=="string")
$object->structure[$previous].=$data;
else
{
$this->SetElementData($object,$this->path.",$element",$data);
$object->structure[$this->path]["Elements"]++;
}
}
};
class xml_parser_class
{
var $xml_parser=0;
var $parser_handler;
var $error="";
var $error_number=0;
var $error_line=0;
var $error_column=0;
var $error_byte_index=0;
var $error_code=0;
var $stream_buffer_size=4096;
var $structure=array();
var $positions=array();
var $store_positions=0;
var $case_folding=0;
var $target_encoding="ISO-8859-1";
var $simplified_xml=0;
var $fail_on_non_simplified_xml=0;
Function xml_parser_start_element_handler($parser,$name,$attrs)
{
if(!strcmp($this->error,""))
$this->parser_handler->StartElement($this,$name,$attrs);
}
Function xml_parser_end_element_handler($parser,$name)
{
if(!strcmp($this->error,""))
$this->parser_handler->EndElement($this,$name);
}
Function xml_parser_character_data_handler($parser,$data)
{
if(!strcmp($this->error,""))
$this->parser_handler->CharacterData($this,$data);
}
Function SetErrorPosition($error_number,$error,$line,$column,$byte_index)
{
$this->error_number=$error_number;
$this->error=$error;
$this->error_line=$line;
$this->error_column=$column;
$this->error_byte_index=$byte_index;
}
Function SetError($error_number,$error)
{
$this->error_number=$error_number;
$this->error=$error;
if($this->xml_parser)
{
$line=xml_get_current_line_number($this->xml_parser);
$column=xml_get_current_column_number($this->xml_parser);
$byte_index=xml_get_current_byte_index($this->xml_parser);
}
else
{
$line=$column=1;
$byte_index=0;
}
$this->SetErrorPosition($error_number,$error,$line,$column,$byte_index);
}
Function Parse($data,$end_of_data)
{
global $xml_parser_handlers;
if(strcmp($this->error,""))
return($this->error);
if(!$this->xml_parser)
{
if(!function_exists("xml_parser_create"))
{
$this->SetError(1,"XML support is not available in this PHP configuration");
return($this->error);
}
if(!($this->xml_parser=xml_parser_create()))
{
$this->SetError(1,"Could not create the XML parser");
return($this->error);
}
xml_parser_set_option($this->xml_parser,XML_OPTION_CASE_FOLDING,$this->case_folding);
xml_parser_set_option($this->xml_parser,XML_OPTION_TARGET_ENCODING,$this->target_encoding);
if(function_exists("xml_set_object"))
{
xml_set_object($this->xml_parser,$this);
$this->parser_handler=new xml_parser_handler_class;
$this->structure=array();
$this->positions=array();
}
else
{
$xml_parser_handlers[$this->xml_parser]=new xml_parser_handler_class;
$xml_parser_handlers[$this->xml_parser]->xml_parser=$this->xml_parser;
$xml_parser_handlers[$this->xml_parser]->store_positions=$this->store_positions;
$xml_parser_handlers[$this->xml_parser]->simplified_xml=$this->simplified_xml;
$xml_parser_handlers[$this->xml_parser]->fail_on_non_simplified_xml=$this->fail_on_non_simplified_xml;
}
xml_set_element_handler($this->xml_parser,"xml_parser_start_element_handler","xml_parser_end_element_handler");
xml_set_character_data_handler($this->xml_parser,"xml_parser_character_data_handler");
}
$parser_ok=xml_parse($this->xml_parser,$data,$end_of_data);
if(!function_exists("xml_set_object"))
$this->error=$xml_parser_handlers[$this->xml_parser]->error;
if(!strcmp($this->error,""))
{
if($parser_ok)
{
if($end_of_data)
{
if(function_exists("xml_set_object"))
Unset($this->parser_handler);
else
{
$this->structure=$xml_parser_handlers[$this->xml_parser]->structure;
$this->positions=$xml_parser_handlers[$this->xml_parser]->positions;
Unset($xml_parser_handlers[$this->xml_parser]);
}
xml_parser_free($this->xml_parser);
$this->xml_parser=0;
}
}
else
$this->SetError(2,"Could not parse data: ".xml_error_string($this->error_code=xml_get_error_code($this->xml_parser)));
}
else
{
if(!function_exists("xml_set_object"))
{
$this->error_number=$xml_parser_handlers[$this->xml_parser]->error_number;
$this->error_code=$xml_parser_handlers[$this->xml_parser]->error_code;
$this->error_line=$xml_parser_handlers[$this->xml_parser]->error_line;
$this->error_column=$xml_parser_handlers[$this->xml_parser]->error_column;
$this->error_byte_index=$xml_parser_handlers[$this->xml_parser]->error_byte_index;
}
}
return($this->error);
}
Function VerifyWhiteSpace($path)
{
if($this->store_positions)
{
$line=$parser->positions[$path]["Line"];
$column=$parser->positions[$path]["Column"];
$byte_index=$parser->positions[$path]["Byte"];
}
else
{
$line=$column=1;
$byte_index=0;
}
if(!IsSet($this->structure[$path]))
{
$this->SetErrorPosition(2,"element path does not exist",$line,$column,$byte_index);
return($this->error);
}
if(GetType($this->structure[$path])!="string")
{
$this->SetErrorPosition(2,"element is not data",$line,$column,$byte_index);
return($this->error);
}
$data=$this->structure[$path];
for($previous_return=0,$position=0;$position<strlen($data);$position++)
{
switch($data[$position])
{
case " ":
case "\t":
$column++;
$byte_index++;
$previous_return=0;
break;
case "\n":
if(!$previous_return)
$line++;
$column=1;
$byte_index++;
$previous_return=0;
break;
case "\r":
$line++;
$column=1;
$byte_index++;
$previous_return=1;
break;
default:
$this->SetErrorPosition(2,"data is not white space",$line,$column,$byte_index);
return($this->error);
}
}
return("");
}
Function ParseStream($stream)
{
if(strcmp($this->error,""))
return($this->error);
do
{
if(!($data=@fread($stream,$this->stream_buffer_size)))
{
if(!feof($stream))
{
$this->SetError(3,"Could not read from input stream".(IsSet($php_errormsg) ? ': '.$php_errormsg : ''));
break;
}
}
if(strcmp($error=$this->Parse($data,feof($stream)),""))
break;
}
while(!feof($stream));
return($this->error);
}
Function ParseFile($file)
{
if(!file_exists($file))
return("the XML file to parse ($file) does not exist");
if(!($definition=@fopen($file,"r")))
return("could not open the XML file ($file)".(IsSet($php_errormsg) ? ': '.$php_errormsg : ''));
$error=$this->ParseStream($definition);
fclose($definition);
return($error);
}
};
Function XMLParseFile(&$parser,$file,$store_positions,$cache="",$case_folding=0,$target_encoding="ISO-8859-1",$simplified_xml=0,$fail_on_non_simplified_xml=0)
{
if(!file_exists($file))
return("the XML file to parse ($file) does not exist");
if(strcmp($cache,""))
{
if(file_exists($cache)
&& filemtime($file)<=filemtime($cache))
{
if(($cache_file=@fopen($cache,"r")))
{
if(function_exists("set_file_buffer"))
set_file_buffer($cache_file,0);
if(!($cache_contents=@fread($cache_file,filesize($cache))))
$error="could not read from the XML cache file $cache".(IsSet($php_errormsg) ? ': '.$php_errormsg : '');
else
$error="";
fclose($cache_file);
if(!strcmp($error,""))
{
if(GetType($parser=unserialize($cache_contents))=="object"
&& IsSet($parser->structure))
{
if(!IsSet($parser->simplified_xml))
$parser->simplified_xml=0;
if(($simplified_xml
|| !$parser->simplified_xml)
&& (!$store_positions
|| $parser->store_positions))
{
return("");
}
}
else
$error="it was not specified a valid cache object in XML file ($cache)";
}
}
else
$error="could not open cache XML file ($cache)".(IsSet($php_errormsg) ? ': '.$php_errormsg : '');
if(strcmp($error,""))
return($error);
}
}
$parser=new xml_parser_class;
$parser->store_positions=$store_positions;
$parser->case_folding=$case_folding;
$parser->target_encoding=$target_encoding;
$parser->simplified_xml=$simplified_xml;
$parser->fail_on_non_simplified_xml=$fail_on_non_simplified_xml;
if(!strcmp($error=$parser->ParseFile($file),"")
&& strcmp($cache,""))
{
if(($cache_file=@fopen($cache,"w")))
{
if(function_exists("set_file_buffer"))
set_file_buffer($cache_file,0);
if(!@fwrite($cache_file,serialize($parser))
|| !@fclose($cache_file))
$error="could to write to the XML cache file ($cache)".(IsSet($php_errormsg) ? ': '.$php_errormsg : '');
if(strcmp($error,""))
unlink($cache);
}
else
$error="could not open for writing to the cache file ($cache)".(IsSet($php_errormsg) ? ': '.$php_errormsg : '');
}
return($error);
}
?>