Code:
<?php
/*
XML Parser Class (php5)
Parseaza un document XML asemanator cu extensia SimpleXML.
*/
class XMLParser
{
/**
* Variabila XML parser
* @var resource
*/
private $parser;
/**
* documentul XML
* @var string
*/
private $xml;
/**
* tag-ul Documentului
*
* @var object
*/
public $document;
/**
* adancimea curenta(stiva)
*
* @var array
*/
private $stack;
/**
* Constructor. Incarca documentul XMl.
*
* @param string $xml continutul fisierului XML
* @return XMLParser
*/
function __construct($xml = '')
{
$this->xml = $xml;
$this->stack = array();
}
/**
* Instantiaza si ruleaza parserul XML al PHP
*/
public function Parse()
{
$this->parser = xml_parser_create();
xml_set_object($this->parser, $this);
xml_set_element_handler($this->parser, 'StartElement', 'EndElement');
xml_set_character_data_handler($this->parser, 'CharacterData');
if (!xml_parse($this->parser, $this->xml))
$this->HandleError(xml_get_error_code($this->parser), xml_get_current_line_number($this->parser), xml_get_current_column_number($this->parser));
xml_parser_free($this->parser);
}
/**
* Trateaza erorile de parsare a XML
*
* @param int $code XML Error Code
* @param int $line Linia la care a avut loc eroarea
* @param int $col Coloana la care a avut loc eroarea
*/
private function HandleError($code, $line, $col)
{
trigger_error('XML Parsing Error at '.$line.':'.$col.'. Error '.$code.': '.xml_error_string($code));
}
/**
* ia referinta catre parintele direct curent
*
* @return object
*/
private function GetStackLocation()
{
//returneaza referinta catre parintele direct curent
$return = &end($this->stack);
return $return;
}
/**
* functia ce se ocupa cu inceputul unui tag
*
* @param resource $parser
* @param string $name
* @param array $attrs
*/
private function StartElement($parser, $name, $attrs = array())
{
$name = strtolower($name);
//verifica daca tagul este de nivel primar(nu are parinte)
if (count($this->stack) == 0)
{
//seteaza document ca tag curent
$this->document = new XMLTag($name, $attrs);
$this->stack = array(&$this->document);
}
//folosim stiva pentru a afla parintele
else
{
// ia referinta catre parintele direct curent
$parent = $this->GetStackLocation();
$parent->AddChild($name, $attrs, count($this->stack));
$this->stack[] = &end($parent->$name);
}
}
/**
* functia ce se ocupa cu sfarsitul unui tag
*
* @param resource $parser
* @param string $name
*/
private function EndElement($parser, $name)
{
//sterge ultima valoare din stiva ca parinte
array_pop($this->stack);
}
/**
* functia ce se ocupa cu datele dintr-un tag
*
* @param resource $parser
* @param string $data
*/
private function CharacterData($parser, $data)
{
//ia referinta din obiectul parinte curent
$tag = $this->GetStackLocation();
//se atribuie date
$tag->tagData .= trim($data);
}
}
/**
* XML Tag Object (php5)
*
* Acest obiect retine toti copiii lui directi in vectorul $children.
* De asemenea acestia sunt stocati dupa tip ca si vectori.
*/
class XMLTag
{
/**
* Vectorul cu atributele tagului XML
*
* @var array
*/
public $tagAttrs;
/**
* Numele tagului
*
* @var string
*/
public $tagName;
/**
* Datele continute de tag
*
*
* @var stat
*/
public $tagData;
/**
* Vectorul cu referintele catre toate obiectele copiilor directi
* ale acestui obiect XML
*
* @var array
*/
public $tagChildren;
/**
* Numarul de parinti ai obiectului XML
* @var int
*/
public $tagParents;
/**
* Constructor
*
* @param string $name
* @param array $attrs
* @param int $parents
* @return XMLTag
*/
function __construct($name, $attrs = array(), $parents = 0)
{
$this->tagAttrs = array_change_key_case($attrs, CASE_LOWER);
$this->tagName = strtolower($name);
$this->tagParents = $parents;
$this->tagChildren = array();
$this->tagData = '';
}
/**
* Adauga un copil direct obiectului
*
* @param string $name
* @param array $attrs
* @param int $parents
*/
public function AddChild($name, $attrs, $parents)
{
if(!isset($this->$name))
$this->$name = array();
//daca tagul are acelasi nume cu un membru din XMLTag, sau cumva vectorul nu a fost creat bine, returneaza o eroare cu mult mai multe informatii fata de erorile normale ale PHP
if(!is_array($this->$name))
{
trigger_error('You have used a reserved name as the name of an XML tag. Please rename the tag named '.$name.' to something other than a reserved name.', E_USER_ERROR);
return;
}
$child = new XMLTag($name, $attrs, $parents);
$this->{$name}[] = &$child;
$this->tagChildren[] = &$child;
}
}
?> |