<?php
/*
* KXParse/2.3
* Initially started in March 2002 By Khalid Al-Kary
* Version 2.0 was started in 24 April 2003 by Khalid Al-Kary
* ----------------------------------------------------------
*/class kxparse {
 /*--[ tree mapper ]--*/
 var $document;
 var $xml;
 var $xml_parser;
  
 /*---[tag selection engine]--*/
 var $curr_tag;/*---[tree dumper]---*/
 var $dump_pos;
 var $dump_temp;
 
 /*----[io handling]--*/
 var $file;
   
/*--------------------------------------------------[the constructor]-----*/
 function kxparse($file=false) {
  $this->file=$file;
  if ($file!=false) {
   $flag=$this->init_mapper();
   if (!$flag) {
    return false;
   }
   $this->init_tree_dumper();
   $this->init_selection_engine();
  } 
 }
/*------------------------------------------[IO handling functions]---------*/
 function load($file=false) {
  if ($file===false) {
   $flag=$this->init_mapper();
   return $flag;
  }
  else {
   $this->file=$file;
   $flag=$this->init_mapper();
   if ($flag) {
    $this->init_tree_dumper();
    $this->init_selection_engine();
   }
   return $flag;
  }
 }
 function save($file=false) {
  if ($file==false) {
   $file=$this->file;
  }
  if (!$file) {
   return false;
  }
  $this->dump_tree();
  $flag=$this->io_put_content($file, $this->dump_temp);
  $this->dump_temp="";
  if ($flag==false) {
   return false;
  }
  return true;
 }
 function load_string($str) {
  $this->xml=$str;
  $this->file=false;
  $flag=$this->init_mapper();
  $this->init_tree_dumper();
  $this->init_selection_engine();
  return $flag;
 }
 function io_put_content($filename, $content) {
  $flag=true;
  $fd=fopen($filename, "wb");
  if ($fd==false) {
   $flag=false;
  }
  else {
   $flag=fwrite($fd, $content);
  }
  fclose($fd);
  return $flag;
 }
 function io_get_content($filename) {
  $fd=fopen($filename,"r");
  $content="";
  if ($fd==false) {
   $content=false;
  }
  else {
   while (!feof($fd)) {
    $content.=fread($fd,4096);
   }
  }
  fclose($fd);
  return $content;
 }
 function io_gen_filename($prefix) {
  $i=0;
  $filename="";
  while (true) {
   if (!file_exists(($i==0) ? $prefix : $prefix.".".$i)) {
    $filename=($i==0) ? $prefix : $prefix.".".$i;
    break;
   }
   $i++;
  }
  return $filename;
 }
 function get_content($reswap=true) {
  $this->dump_tree();
  $val=$this->dump_temp;
  $this->dump_temp="";
  return $val;  
 }
 function get_file_name() {
  return $this->file;
 }

解决方案 »

  1. /*------------------------------------------[ xml tree mapper (expat-based) ]-*/
     function init_mapper() {
      $this->document['pi']=array();
      $this->document['children']=array(0);
      $this->document['internal']=0;
      $this->document['length']=0;
      $this->curr_tag=&$this->document;
      $this->xml_parser=xml_parser_create();
      xml_set_object($this->xml_parser,$this);
      xml_set_element_handler($this->xml_parser,"start_element_handler","end_element_handler");
      xml_set_character_data_handler($this->xml_parser,"cdata_handler"); 
      xml_set_processing_instruction_handler($this->xml_parser,"pi_handler");
      xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, 0);
      if ($this->file) {
       $fd=fopen($this->file,"r");
       $content="";
       if (!$fd) {
        return false;
       }
       while (!feof($fd)) {
        $content=fread($fd,4096);
        xml_parse($this->xml_parser,$content);
       }
       fclose($fd);
      }
      else {
       if ($this->xml=="") {
        return false;
       }
       xml_parse($this->xml_parser,$this->xml);
      }  
      $this->init_selection_engine();
      return true;
     }
     function start_element_handler($parser, $name, $attribs) {
      $this->curr_tag['length']++;
      if (!isset($this->curr_tag['children']['?'])) {
       $this->curr_tag['children']['?']=array(0);
      }
      if (!isset($this->curr_tag['children'][$name])) {
       $this->curr_tag['children'][$name]=array(0);
      }
      $last_child=count($this->curr_tag['children'][$name]);
      $anon_last_child=count($this->curr_tag['children']['?']);
      $this->curr_tag['children'][$name][$last_child]=array();
      $this->curr_tag['children'][$name][$last_child]['attribs']=$attribs;
      $this->curr_tag['children'][$name][$last_child]['children']=array("?" => array(0));
      $this->curr_tag['children'][$name][$last_child]['parent']=&$this->curr_tag;
      $this->curr_tag['children'][$name][$last_child]['name']=$name;
      $this->curr_tag['children'][$name][$last_child]['length']=0;
      $this->curr_tag['children'][$name][$last_child]['text']="";
      $this->curr_tag['children'][$name][$last_child]['anon_index']=$anon_last_child;
      $this->curr_tag['children'][$name][$last_child]['index']=$last_child;
      $this->curr_tag['children']['?'][$anon_last_child]=&$this->curr_tag['children'][$name][$last_child];
      $this->curr_tag=&$this->curr_tag['children'][$name][$last_child];
     }
     function end_element_handler($parser, $name) {
      $this->curr_tag=&$this->curr_tag['parent'];
     }
     function cdata_handler($parser, $data) {
      $this->curr_tag['text'].=$data;
     }
     function pi_handler($parser, $target, $data) {
      $this->document['pi'][$target]=$data;
     }
    /*------------------------------------------[tree dumper]-----------------------*/
     function init_tree_dumper() {
      $this->dump_temp="";
      $this->dump_pos=0;
     }
     function dump_tree() {
      $this->init_tree_dumper();
      $sec_curr_tag=&$this->curr_tag;
      $this->curr_tag=&$this->document;  $karr=array_keys($this->document['pi']);
      $ecount=count($karr);
      
      for ($i=0; $i<$ecount; $i++) {
       $this->dump_temp.="<?".$karr[$i]." ".$this->htmlencode($this->document['pi'][$karr[$i]], true)."?>";
       $this->dump_pos+=strlen($karr[$i])+strlen($this->htmlencode($this->document['pi'][$karr[$i]], true))+5;
      }
      unset($karr);
      unset($ecount);
      
      $this->curr_tag=&$this->document['children']['?'][1];
      $this->dump_current_element();
      $this->curr_tag=&$sec_curr_tag;
     }
     function dump_current_element() {
      $internal=0;
      if ($this->curr_tag['length']>0 || (isset($this->curr_tag['text']) && $this->curr_tag['text']!="")) {
       $internal=0;
      }
      else {
       $internal=1;
      }
      if ($this->dump_pos<strlen($this->dump_temp)) {
       if ($internal==0) {
        $this->dump_temp=substr_replace($this->dump_temp,"<".$this->curr_tag['name']."></".$this->curr_tag['name'].">",$this->dump_pos,0);
       }
       else {
        $this->dump_temp=substr_replace($this->dump_temp,"<".$this->curr_tag['name']."/>",$this->dump_pos,0);   
       } 
      }
      else {
       if ($internal==0) {
        $this->dump_temp.="<".$this->curr_tag['name']."></".$this->curr_tag['name'].">";
       }
       else {
        $this->dump_temp.="<".$this->curr_tag['name']."/>";
       } 
      }
      if (count($this->curr_tag['attribs'])>0) {
       $this->dump_pos+=strlen($this->curr_tag['name'])+1;
       $karr=array_keys($this->curr_tag['attribs']);
       $ecount=count($karr);
       
       for ($i=0;$i<$ecount;$i++) {
        $this->dump_temp=substr_replace($this->dump_temp," ",$this->dump_pos++,0);
        $this->dump_temp=substr_replace($this->dump_temp,$karr[$i]."=\"".$this->htmlencode($this->curr_tag['attribs'][$karr[$i]], true)."\"",$this->dump_pos,0);
        $this->dump_pos+=strlen($karr[$i])+strlen($this->htmlencode($this->curr_tag['attribs'][$karr[$i]], true))+3;
       }
       unset($karr);
       unset($ecount);
       if ($internal==1) {
        $this->dump_pos+=2;
       }
      }
      else {
       if ($internal==0) {
        $this->dump_pos+=strlen($this->curr_tag['name'])+1;
       }
       else {
        $this->dump_pos+=strlen($this->curr_tag['name'])+3;
       } 
      }
      if ($internal==1) {
       $this->curr_tag=&$this->curr_tag['parent'];
      }
      else {
       $this->dump_pos+=1;
       $this->dump_temp=substr_replace($this->dump_temp,$this->htmlencode($this->curr_tag['text']),$this->dump_pos,0);
       $this->dump_pos+=strlen($this->htmlencode($this->curr_tag['text']));
       $ecount=count($this->curr_tag['children']['?']);
       for ($i=1;$i<$ecount;$i++) {
        $this->curr_tag=&$this->curr_tag['children']['?'][$i];
        $this->dump_current_tag();
       }
       unset($ecount);
       $this->dump_pos+=3+strlen($this->curr_tag['name']);
       $this->curr_tag=&$this->curr_tag['parent'];
      }
     }
      

  2. /*------------------------------------------------[the element selection engine]--*/
     function init_selection_engine() {
      $this->curr_tag=&$this->document['children']['?'][1];
     }
     function select($tname,$tindex) {
      if ($tname==="") {
       return true;
      }
      
      $pre_sel=&$this->curr_tag;
      $name_arr=$this->explode_collect(":",$tname);
      $index_arr=explode(":",$tindex);
      $reg_array=array();
      
      
      if ($name_arr[0]!=="-" && $index_arr[0]!=="-") {
       $this->curr_tag=&$this->document;
      }
      else {
       if ($name_arr[0]=="-") {
        $name_arr=&array_slice($name_arr,1);
       }
       if ($index_arr[0]=="-") {
        $index_arr=&array_slice($index_arr,1);
       }
      }
      
      $name_count=count($name_arr);
      $index_count=count($index_arr);  if ($name_count!=$index_count) {
       $this->curr_tag=&$pre_sel;
       return false;
      }  for ($i=0;$i<$name_count;$i++) {
       if (preg_match("/R\(.{1,}\)/i",$name_arr[$i])===1) {
        $patern=substr($name_arr[$i],2,strlen($name_arr[$i])-3);
        $count=0;
        
        if (isset($this->curr_tag['children']['regs'][$patern])) {
         $reg_arr=&$this->curr_tag['children']['regs'][$patern];
         $count=count($reg_arr);
        }
        else {
         $reg_arr=array(0);
         $count=1;
         $ecount=count($this->curr_tag['children']['?']);
        
         for ($l=1;$l<$ecount;$l++) {
          if (preg_match($patern,$this->curr_tag['children']['?'][$l]['name'])===1) {
           $reg_arr[$count]=&$this->curr_tag['children']['?'][$l];
           $count++;
          }
         }
         $this->curr_tag['children']['regs'][$patern]=&$reg_arr;
         $count--;
        }
        if ($index_arr[$i]==="?") {
         return $count;
        }
        else if ($index_arr[$i]<1) {
         $children_count=$count;
         $index_arr[$i]=$children_count+$index_arr[$i];
         
         if ($index_arr[$i]<1) {
          $this->curr_tag=&$pre_sel;
          return false;
         }
        }
        if (isset($reg_arr[$index_arr[$i]])) {
         $this->curr_tag=&$reg_arr[$index_arr[$i]];
        }
        else {
        $this->curr_tag=&$pre_sel;
         return false;
        }
       }
       else if (strpos($name_arr[$i],"!")===0) {
        $val=$this->cselect(substr($name_arr[$i],1),$index_arr[$i]);
        if ($index_arr[$i]==="?") {
         return $val;
        }
        else if ($val===false) {
         $this->curr_tag=&$pre_sel;
         return false;
        }
       }
       else {
        if ($index_arr[$i]==="?") {
         $returned_count=count($this->curr_tag['children'][$name_arr[$i]]);
         return ($returned_count<=0) ? $returned_count : $returned_count-1;
        }
        else if ($index_arr[$i]<1) {
         $children_count=count($this->curr_tag['children'][$name_arr[$i]]);
         $index_arr[$i]=$children_count+$index_arr[$i];
         
         if ($index_arr[$i]<1) {
          $this->curr_tag=&$pre_sel;
          return false;
         }
        }
        if (isset($this->curr_tag['children'][$name_arr[$i]][$index_arr[$i]])) {
         $this->curr_tag=&$this->curr_tag['children'][$name_arr[$i]][$index_arr[$i]];
        }
        else {
         $this->curr_tag=&$pre_sel;
         return false;
        }
       }
      }
      return true;
     }
      

类似问题 »