<?php

/**
 * 
 * SWXml | XML API for SWX by Florian Plag. This API is a generic XML parser. 
 * 
 * @author	Florian Plag
 * @copyright	2007 Florian plag. All Rights Reserved. 
 * @license	Open Source MIT License
 * @link 	http://www.video-flash.de
 * @link 	http://swxformat.org
 * 
**/

class SWXml {
	
	
	var $xml_parser;	// xml parser object
    var $data;			// array that stores all the XML information
	
	var $NameOfFirstNode = ""; // name of the first XML node


	/**
	 * This function parses an XML feed and returns an array with the XML data. 
	 *
	 * @param	Location of the XML file (e.g. http://www.video-flash.de/index.php/feed/atom/)	
	 * 
	 * @return The function returns an array containing the feed data.
	 **/

	
	function parseXML($url){
		

		// ::::: set up XML parser	:::::
		
		// create an xml parser
		$this->xml_parser = xml_parser_create();
		
		// use XML parser within an object
		xml_set_object($this->xml_parser, $this);
		
		// set up functions for start and end element
		xml_set_element_handler($this->xml_parser, "_startHandler", "_endHandler");
		
		// set up handler for tag content
		xml_set_character_data_handler($this->xml_parser, '_dataHandler');		

	
		// ::::: open XML feed	:::::
		
		/// if file is not found, error is triggered by file_get_contents
		$filedata = @file_get_contents($url);	
		
		if ($filedata != false) {	
					
				// if file is valid ... (no errors)			
		    	if ( xml_parse($this->xml_parser, $filedata) != false) {
					
					// nest data into a final array ...
					$finalArray = array();	
					
					// ... with the name of the first xml node			
					$finalArray[$this->NameOfFirstNode] = $this->data;
													
					// return final array				
					return $finalArray;
					
		    	}
		
		
				// (file is not valid / parse error)
				else {
				
					// save error code from xml parser
					$err['errorcode'] = xml_get_error_code($this->xml_parser);
					$err['errormessage'] = xml_error_string( xml_get_error_code($this->xml_parser) );
					 
					// trigger error				
					trigger_error("Parse error " . $err['errorcode'] . ": " . $err['errormessage'] , E_USER_ERROR);
				}
			

		
		}

		// free XML parser
		xml_parser_free($this->xml_parser);

	}



	/**
	 *  (private function) startHandler of an XML node
	 *
	 * @param	name of parser
	 * @param	name of node
	 * @param	attributes		
	 * 
	 * @return 
	 **/
	

   function _startHandler($parser, $nameOfNode, $attributes) {	
	
		// change node name to lowercase
		$nameOfNode = strtolower($nameOfNode);
		
		// replace colon with NS (= Namespace)
		$nameOfNode = str_replace(":", "NS", $nameOfNode);
		
		// create temporary array
		$temp[$nameOfNode] = "";
		
		// save node name for the very first node
		if ($this->NameOfFirstNode == "") {
			$this->NameOfFirstNode = $nameOfNode;
		}
		
		// are there attributes?
		if ($attributes) {	
			
			// only lower case letters
			$attributes = array_change_key_case($attributes, CASE_LOWER);	
				
			// flip keys with values	
			$attributes = array_flip($attributes);
			
			// replace colon with 'NS' (=namespace)
			$pattern[0] = "/:/";
			$replacement[0] = "NS";
			$attributes = preg_replace($pattern, $replacement, $attributes);
			
			// flip back	
			$attributes = array_flip($attributes);			
			
			// add attributes to temp array
			$temp['attributes'] = $attributes;	
		}
		
		// save temp array to data array
    	$this->data[] = $temp;
	
      }


	/**
	 *  (private function) _endHandler of an XML noe
	 *
	 * @param	name of parser
	 * @param	name of node	
	 * 
	 * @return 
	 **/

   function _endHandler($parser, $nameOfNode) {	

		// count array
        if (count($this->data) > 1) {
	
			// pop last item into temp array
	        $temp = array_pop($this->data);
	
			// position: last position minus one
         	$index = count($this->data) - 1;

			// save temp array to data array
         	$this->data[$index][key($temp)][] = $temp;
		}

   }


	/**
	 *  (private function) _dataHandler of an XML node
	 *
	 * @param	name of parser
	 * @param	content/text of the XML node
	 * 
	 * @return 
	 **/
	
   function _dataHandler($parser, $text) {
	
	  // if text is available ... 
      if($text = trim($text)) {
	
		 // last position of array minus one	
         $index = count($this->data) -1;

		 // if variable exists, add ...
         if ( isset($this->data[$index]['text']) ) {
	 		$this->data[$index]['text'] .= $text;
		 }
		
		 // else create
         else {
			$this->data[$index]['text'] = $text;
		 }
      }
   }


	
} // end of class

?>