Tree-Klasse anpassen

crazyPower

Mitglied
Hallo,
ich benutze die Klasse xmltree von Steve Hamilton, um einen PHP-Treeview auf zubauen. Ich habe nun aber folgendes Problem:
Ich habe einen Tree von knapp 5000 Nodes, d.h. die xml Datei, die bei jedem Seiten aufruf geparsed werden muss ist 1,2 MB groß. Das wiederum bedeutet, dass der Aufbau doch relativ lange dauert.

Wie kann ich die Klasse nun so umbauen, dass er ab dem ersten Treenode nur noch zwei Ebenen tiefer parsed, und wenn dann wieder eine Ebene tiefer geklickt wurde, wiederum zwei Ebenen geparst werden.

hier die Klasse:
PHP:
<?php 
/*[ Name: xmltree.php ] */
/*[ Author: Steve Hamilton ] */
/*[ WWW: http://www.phphelper.net ] */
/*[ Version: 1.0.1 ] */
/*[ Created: 07/11/2002 ] */
/*[ GPL:
	xmltree.php - PHP Class for file uploading
	Copyright (C) 2001 Steve Hamilton & phphelper.net
	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  http://www.gnu.org/licenses/gpl.txt
 ]
*/
class tree { 
 
  var $file = "display.xml"; // Default file name 
  var $fontSize = -1; // Default font size 
  var $expandAll = 0; // 1 = yes, 0 = no
  
  var $imgPath = "treeicon/"; 
  // Image type array. Determined in NODE paramater "type" in xml 
  // ie <node Name="Node3" Type="pdf"> would show the image associated 
  // with pdf if it were an ending node(leaf) 
  // "leaf" is the default leaf image 
  var $imgType = array("leaf" => "t_leaf.gif", 
					   "tplus" => "t_tplus.gif", 
					   "cplus" => "t_cplus.gif", 
					   "tminus" => "t_tminus.gif", 
					   "cminus" => "t_cminus.gif", 
					   "mbar" => "t_bar.gif", 
					   "mtee" => "t_tee.gif", 
					   "mcorner" => "t_c.gif", 
					   "mspace" => "t_dot.gif", 
						
						
					   "audio" => "t_audio.gif", 
					   "disk" => "t_disk.gif", 
					   "document" => "t_web.gif", 
					   "email" => "t_email.gif", 
					   "help" => "t_help.gif", 
					   "ini" => "t_ini.gif", 
					   "music" => "t_music.gif", 
					   "pdf" => "t_pdf.gif", 
					   "text" => "t_text.gif", 
					   "web" => "t_web.gif", 
					   "word" => "t_word.gif", 
					   "write" => "t_write.gif" 
					   ); 
						
  // Internal variables. No need to edit these						
  var $xmlDepth = array(); 
  var $treeDepth; 
  var $lastElement; 
  var $nodeName; 
  var $nodeCount ; 
  var $maxLevel; 
  function startElement($parser, $name, $attrs) { 
	$this->lastElement = $name; 
	if($name=="TREE"){ 
	  $this->node[0]["treeDepth"]="0"; 
	  $this->node[0]["NAME"]="<a href=\"tester\">tester</a>";//trim($attrs["NAME"]);
	  $this->node[0]["TYPE"]=trim($attrs["TYPE"]); 
	  $this->node[0]["LINK"]=trim($attrs["LINK"]); 
	  $this->node[0]["TARGET"]=trim($attrs["TARGET"]); 
	  $this->node[0]["FORM"]=trim($attrs["FORM"]); 
	} 
	if($name=="NODE"){ 
	  $this->treeDepth++; 
	  if($this->treeDepth > $this->maxLevel){ 
		$this->maxLevel = $this->treeDepth; 
	  } 
	  $this->nodeCount++; 
	  $this->nodeID = $this->nodeCount; 
	  $this->node[$this->nodeID]["treeDepth"] = $this->treeDepth; 
	
	} 
	while (list($k, $v) = each($attrs)) { 
	  $this->node[$this->nodeID][$k] = trim($v); 
	} 
	$this->xmlDepth[$parser]++; 
  } // end startElement($parser, $name, $attrs) 
  function dataElement($parser, $data) { 
	$this->node[$this->nodeID][$this->lastElement] .= trim($data); 
  } // end dataElement($parser, $data) 
  function endElement($parser, $name) { 
	if($name=="NODE"){ 
	  $this->treeDepth--; 
	  $this->node[$this->nodeID]["last"]=1; 
	} 
	$this->xmlDepth[$parser]--; 
  } // endElement($parser, $name) 
  function makeTree($XML_FILE = ""){ 
  if(get_magic_quotes_runtime()){
   set_magic_quotes_runtime (0);
   $mq = 1;
  }
	$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, "dataElement"); 
	if($XML_FILE){
	  if (!($fp = fopen($XML_FILE, "r"))) {		
		die("Could not open XML file"); 
	  }
	}
	else{
	  if (!($fp = fopen($this->file, "r"))) {  
		die("Could not open XML file"); 
	  }
	}
	
	while ($data = fread($fp, 4096)) { 
	  if (!xml_parse($this->parser, $data, feof($fp))) { 
		die(sprintf("XML error: %s at line %d", 
					xml_error_string(xml_get_error_code($this->parser)), 
					xml_get_current_line_number($this->parser))); 
	  } 
	} 
	xml_parser_free($this->parser);
  if($mq){
   set_magic_quotes_runtime (1);
  } 
	return $this->displayTree(); 
	
  } // end makeTree() 
  
  
  
  
  function displayTree(){ 
	global $e;
	$e=$_GET['e'];
	$expands = explode(",",$e); 
	$totalExpands = count($expands); 
	// Set branches to expand and make visible 
	foreach($expands as $x){ 
	  $expand[$x] = 1; 
	} 
	// First force depth 0 branches to be visible. Defined as <tree> tag in xml 
	$visible[0]=1; 
	for($aNode=0;$aNode<=$this->nodeCount;$aNode++){ 
	  if($this->expandAll == 1 && !$e){ 
		$visible[$aNode] = 1; 
		$expand[$aNode] = 1; 
	  } 
	  if($this->node[$aNode]["treeDepth"]<=1){
		$visible[$aNode] = 1; 
	  } 
	  if($this->node[$aNode+1]["treeDepth"] > $this->node[$aNode]["treeDepth"]){ 
		$expandable[$aNode]=1; 
	  } 
	  else{ 
		if($this->expandAll == 1 && !$e){ 
		  if($expandable[$aNode]== 1){ 
			$expand[$aNode] = 1; 
		  } 
		}		
	  } 
	} 
		
	// Now make everything visible that is expanded + 1 level 
	for ($i=0; $i<=$totalExpands; $i++)  { 
	  $aNode=$expands[$i]; 
	  
	  if ($aNode<$this->nodeCount && $visible[$aNode]==1 && $expand[$aNode]==1) { 
		$nextNode=$aNode+1; 
		while ( $this->node[$nextNode]["treeDepth"] > $this->node[$aNode]["treeDepth"] ) { 
		  if($this->node[$nextNode]["treeDepth"]== $this->node[$aNode]["treeDepth"]+1){ 
			$visible[$nextNode] = 1; 
			$lastnode = $nextNode; 
		  } 
		  $nextNode++; 
		} 
		$lastNode[$lastnode] = 1; 
	  } 
	}	  
	$lastlevel = $this->maxLevel; 
	for ($i=$this->nodeCount-1; $i>=0; $i--) { 
	  if ( $this->node[$i]["treeDepth"]< $lastlevel) { 
		for ($nextNode=$this->node[$i]["treeDepth"]+1; $nextNode < $this->maxLevel; $nextNode++) { 
		  $treeLevels[$nextNode]=0; 
		} 
	  } 
	  if ( $treeLevels[$this->node[$i]["treeDepth"]]==0 ) { 
		$treeLevels[$this->node[$i]["treeDepth"]]=1; 
		$lastNode[$i]=1; 
	  } 
	  $lastlevel=$this->node[$i]["treeDepth"]; 
	} 
	$treeHTML = "<br>"; 
	$treeHTML .= "<table cellspacing=0 cellpadding=0 border=0  cols=" .
	($this->maxLevel+3) . " width=" . ($this->maxLevel*16+$width2) . ">\n"; 
	$treeHTML .= "<tr>"; 
	for ($i=0; $i<$this->maxLevel; $i++)   $treeHTML .= "<td width=16></td>"; 
	  $treeHTML .="<td></td></tr>\n"; 
	  for ($i=0; $i<$this->maxLevel; $i++) $treeLevels[$i]=1; 
		for($aNode=0;$aNode<$this->nodeCount+1;$aNode++){ 
		  $nextNode = $aNode+1; 
		  if($visible[$aNode]==1){ 
			$treeHTML .= "<tr>\n"; 
			for ($i=0; $i<$this->node[$aNode]["treeDepth"]-1; $i++) { 
			  if ($treeLevels[$i]==1) { 
				$treeHTML .= "<td><img src=\"". $this->imgPath . $this->imgType["mbar"]. "\" alt=\"\"></td>"; 
			  } 
			  else { 
				$treeHTML .= "<td><img src=\"" .$this->imgPath . $this->imgType["mspace"] . "\" alt=\" \"></td>"; 
			  } 
			} 
			if ($this->node[$aNode]["treeDepth"]) { 
			  if ($lastNode[$aNode]) { 
				//if(bcsub ($this->nodeCount , 1)  ==  $aNode - 7){ 
				//  $Img = $this->imgType["mtee"] ; 
				//}
				//else { 
				  $Img = $this->imgType["mcorner"] ; 
				//} 
				$treeHTML .= "<td><img src=\"" . $this->imgPath . $Img . "\" alt=\"\"></td>"; 
				$treeLevels[$this->node[$aNode]["treeDepth"]-1]=0; 
			  } 
			else { 
			  if($this->expandAll == 1){ 
				if($this->nodeCount  ==  $aNode ){ 
				  $Img2 = $this->imgType["mcorner"] ; 
				}
			  else { 
				$Img2 = $this->imgType["mtee"] ;
			  } 
			}
		 else{ 
		   $Img2 = $this->imgType["mtee"] ;
		 } 
		 $treeHTML .= "<td><img src=\"" . $this->imgPath . $Img2 . "\" alt=\"\"></td>"; 
		 $treeLevels[$this->node[$aNode]["treeDepth"]-1]=1; 
		} 
	  } 
	  if ($this->node[$nextNode]["treeDepth"]>$this->node[$aNode]["treeDepth"]) { 
		$postString="?e="; 
		for ($i=0; $i<$this->nodeCount; $i++) { 
		  if ($expand[$i]==1 xor $aNode==$i) { 
			if ($postString != "?e=") $postString .= ","; 
			  $postString .= $i; 
			} 
		  } 
		  if ($expand[$aNode]==0) { 
			if($lastNode[$aNode]){ 
			  $treeHTML .= "<td><a href=\"" . $PHP_SELF . $postString ."\"><img src=\"" . $this->imgPath . $this->imgType["cplus"] . "\" border=\"0\" alt=\"expand\"></a></td>\n"; 
			} 
			else{ 
			  $treeHTML .= "<td><a href=\"" . $PHP_SELF . $postString ."\"><img src=\"" . $this->imgPath . $this->imgType["tplus"] . "\" border=\"0\" alt=\"expand\"></a></td>\n";
			} 
		  } 
		  else { 
			$treeHTML .= "<td><a href=\"" . $PHP_SELF  . $postString ."\"><img src=\"" . $this->imgPath . $this->imgType["tminus"] . "\" border=\"0\" alt=\"collapse\"></a></td>\n"; 
		  } 
		} 
	  else { 
		if($this->node[$aNode]["TYPE"]){ 
		  if($this->imgPath . $this->imgType[$this->node[$aNode]["TYPE"]]){ 
			$leafImg = $this->imgPath . $this->imgType[$this->node[$aNode]["TYPE"]]; 
		  } 
		  else{ 
			$leafImg = $this->imgPath . $this->imgType["leaf"]; 
		  } 
		} 
		if($leafImg ){ 
		   $treeHTML .= "<td><img src=\"" . $leafImg . "\" alt=\"\"></td>\n"; 
		} 
		else{ 
		   $treeHTML .= "<td></td>"; 
		} 
	  } 
	  if ($this->node[$aNode]["SUB"] =="0" OR $aNode==0) { 
		$treeHTML .= "<td  valign=top colspan=" . ($this->maxLevel-$this->node[$aNode]["treeDepth"]+3) ." nowrap >"; 
		 $treeHTML .= "<font face =\"tahoma\" size=\"". $this->fontSize . "\">&nbsp;"; 
		 $treeHTML .=  $this->node[$aNode]["NAME"] . "<br></font>"; 
		 $treeHTML .= "</td>\n"; 
	  } 
	  else { 
		$treeHTML .= "<td width='100%' colspan=" . ($this->maxLevel-$this->node[$aNode]["treeDepth"]+3) ." nowrap >";
		$treeHTML .= "<font size=\"". $this->fontSize . "\">"; 
		$treeHTML .= "<a href=\"" . $this->node[$aNode]["LINK"]; 
		if($aNode==0){ 
		   $treeHTML .= "?e=0"; 
		} 
		else{ 
		if($this->node[$aNode]["LINK"] == ""){ 
			$treeHTML .= "?e=" . $e; 
		} 
		
	 } 
	 $treeHTML .= "\" "; 
	 if($this->node[$aNode]["TARGET"]){ 
	   $treeHTML .= "target=\"" . $this->node[$aNode]["TARGET"] . "\""; 
	 } 
	 $treeHTML .= ">" . $this->node[$aNode]["NAME"] . "</font></a></td>\n"; 
	} 
   $treeHTML .= "</tr>\n"; 
   } 
  } 
  $treeHTML .= "</table></font>\n"; 
  Return $treeHTML; 
 } // end displayTree() 
  
  
  
  
} // end class 
?>

hier noch eine beispiel xml
Code:
<?xml version="1.0"?>
<tree name="Main Menu">
  <node name="Node1" Type="document" link="blubb.php">
	<node>
	  <name>Node2</name>
	  <type>pdf</type>
	  <link>#</link>
	</node>
	<node Name="Node3" Type="pdf">
	  <link>#</link>
	  <node Name="Node4" Type="text">
		<link>#</link>
	  </node>
	</node>
	<node Name="Node5" Type="document">
	  <link>#</link>
	  <node Name="Node6" Type="email">
		<link>#</link>
	  </node>
	</node>
  </node>
  <node Name="Node7" Type="document">
	<node name="Node8" Type="document">
	  <link target="_new">#</link>
	</node>
	<node name="Node9" Type="document">
	  <node Name="Node10" Type="document">
		<link >tree.php</link>
	  </node>
	</node>	
  </node>  
</tree>

cu

cP
 
Zurück