<?php
/*============================================================================
 ||	#######################################################################	||
 ||																			||
 ||	Powered by Dvbbs.PHP 1.0.0 2000 - 2006 Cndw.Com					||
 ||	author:			xiaodu@dv												||
 ||	date:			2006-09-30												||
 ||	modified date:	2006-09-30												||
 ||																			||
 ||	#######################################################################	||
 ============================================================================*/
class XML2PHPArray
{
	var $_xmldata = '';
	var $phparray = array();
	var $_stack = array();
	var $_stacklayer = -1;
	var $_currenttagname = '';
	var $_strcdata = '';
	var $mXmlAttributesFilter = '';

	function registerAttributesFilter($filter)
	{
		settype($filter, 'string');
		$this->mXmlAttributesFilter = $filter;
	}//end function registerAttributesFilter
	function _tag_open(&$parser, $tagname, &$attributes)
	{
		$this->_strcdata = '';
		$this->_stacklayer++;
		$arraytmp = '';
		$this->_currenttagname = $tagname;
		if (!empty($attributes)) {
			!empty($this->mXmlAttributesFilter) AND ($func_name = $this->mXmlAttributesFilter) AND  ($func_name($attributes));
			$arraytmp = array();
			foreach ($attributes AS $name => $val) {
				$arraytmp[$name] = $val;
			}//end foreach
		}
		if (0 === $this->_stacklayer) {
			$this->phparray = $arraytmp;
			$this->_stack[$this->_stacklayer] =& $this->phparray;
		} else {
			$parentnode =& $this->_stack[$this->_stacklayer-1];
			$currentnode =& $parentnode[$tagname];
			if (!isset($currentnode)) {
				$currentnode = $arraytmp;
			} else {
				if (!isset($currentnode[0])) {
					$currentnode = array(0=>$currentnode, 1=>$arraytmp);
				} else {
					$currentnode[] = $arraytmp;
				}
				$index = count($currentnode) - 1;
				$currentnode =& $currentnode[$index];
			}
			$this->_stack[$this->_stacklayer] =& $currentnode;
		}
	}//end function _tag_open
	function _cdata(&$parser, &$cdata)
	{
		$this->_strcdata .= $cdata;
	}
	function _tag_close(&$parser, $tagname)
	{
		$cdata = $this->unescape_cdata($this->_strcdata);
		$currentnode =& $this->_stack[$this->_stacklayer];
		if ('' === $currentnode) {
			$currentnode = $cdata;
		} elseif (isset($currentnode['value'])) {
			$currentnode['value'] = array(0=>$currentnode['value'], 1=>$cdata);
		} else {
			$currentnode['value'] = $cdata;
		}
		$this->_stacklayer--;
	}//end function _tag_close
	function parse_file($datafile, $encoding = 'UTF-8', $clearcache = true)
	{
		if (is_file($datafile)) {
			$xmldata = file_get_contents($datafile);
			if ($xmldata) {
				$this->parse_data($xmldata, $encoding, $clearcache);
			}
		}
	}//end function parse_file
	function parse_data(&$xmldata, $encoding = 'UTF-8', $clearcache = true)
	{
		$this->_prepoint = $this->_point = null;
		$parser = xml_parser_create($encoding);
		
		xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
		xml_set_character_data_handler($parser, array(&$this, '_cdata'));
		xml_set_element_handler($parser, array(&$this, '_tag_open'), array(&$this, '_tag_close'));
		
		xml_parse($parser, $xmldata);
		$err = xml_get_error_code($parser);
		xml_parser_free($parser);
		unset($parser);
	}//end function parse

	function unescape_cdata(&$cdata)
	{
		static $arrsearch = array('&laquo;![CDATA[', ']]&raquo;', "\r\n", "\n");
		static $arrreplace = array('<![CDATA[', ']]>', "\n", "\r\n");
		return str_replace($arrsearch, $arrreplace, $cdata);
	}
}// end class XML2PHPArray
?>