Clear(); // in case if Parse method is called more then one time $xml_parser = xml_parser_create(); xml_set_element_handler( $xml_parser, Array(&$this, 'startElement'), Array(&$this, 'endElement') ); xml_set_character_data_handler( $xml_parser, Array(&$this, 'characterData') ); if (!xml_parse($xml_parser, $xml, 1)) { trigger_error(sprintf('XML error: %s at line %d'), xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser), E_USER_WARNING); } xml_parser_free($xml_parser); return $this->RootElement; } function startElement(&$Parser, &$Elem, $Attrs) { $parent =& $this->CurrentElement; $this->CurrentElement =& new kXMLNode($Elem, $Attrs); if (is_null($this->RootElement)) { $this->RootElement =& $this->CurrentElement; } if (!is_null($parent)) { $parent->AddChild($this->CurrentElement); } } function characterData($Parser, $Line) { $this->CurrentElement->AppendData($Line); } function endElement($Parser, $Elem) { if ($this->CurrentElement->Parent != null) { $this->CurrentElement =& $this->CurrentElement->Parent; } } function Clear() { $this->RootElement = null; $this->CurrentElement = null; } } class kXMLNode { var $Name = null; var $Attributes = array(); var $Children = array(); var $Data = null; var $firstChild = null; var $lastChild = null; /** * Parent node * * @var kXMLNode */ var $Parent = null; /** * Node position relative to other nodes of it's parent * * @var int */ var $Position = 0; function kXMLNode($name, $attrs = array()) { $this->Name = $name; $this->Attributes = $attrs; } function SetParent(&$elem) { $this->Parent =& $elem; } /** * Adds new child to current node * * @param kXMLNode $a_child */ function AddChild(&$a_child) { $node_count = count($this->Children); $a_child->Position = $node_count; if ($node_count == 0) { $this->firstChild =& $a_child; $this->lastChild =& $a_child; } else { $this->lastChild =& $a_child; } $this->Children[] =& $a_child; $a_child->SetParent($this); } function AppendData($data) { $this->Data .= $data; } function &GetChild($path) { $entries = explode('/', strtoupper($path)); $cur = array_shift($entries); if ($cur == $this->Name) $cur = array_shift($entries); if (!$cur) return $this; if (!isset($this->Children[$cur])) return false; $left = implode('/', $entries); if (!$left) return $this->Children[$cur]; return $this->Children[$cur]->GetChild($left); } function GetChildValue($path) { $child =& $this->GetChild($path); if ($child !== false) { return $child->Data; } } function &GetChildByPosition($position) { if ($position < count($this->Children) ) { return $this->Children[$position]; } else { $false = false; return $false; } } function &FindChild($name) { $name = strtoupper($name); if ($this->Name == $name) return $this; // if (isset($this->Children[$name])) return $this->Children[$name]; // $children = array_keys($this->Children); foreach ($this->Children as $elem) { $child =& $elem->FindChild($name); if ($child !== false) { return $child; } } return false; } function FindChildValue($name, $attr=null) { $child =& $this->FindChild($name); if ($child !== false) { if (isset($attr)) { return $child->Attributes[strtoupper($attr)]; } return $child->Data; } } /** * Returns next node to this, false in case of end list * * @return kXMLNode */ function &NextSibling() { if (!is_null($this->Parent)) { $ret =& $this->Parent->GetChildByPosition($this->Position + 1); return $ret; } else { $false = false; return $false; } } } ?>