xmlfile = $filename; if($create){ $this->doc = new DOMDocument('1.0', 'UTF-8'); $newnode = $this->doc->appendChild($this->doc->createElement('operation_layer')); $newnode->appendChild($this->doc ->createComment('Root Context')); } } /** * 座標と操作内容からXMLデータ(DOMオブジェクト)を作成する。 * @access private * @param int $x1 操作範囲始点のX座標 * @param int $y1 操作範囲始点のY座標 * @param int $x2 操作範囲終点のX座標 * @param int $y2 操作範囲終点のY座標 * @param string $operation 操作XML引数 * @param string $comment コメント */ public function createXMLStringFromPositions($x1,$y1,$x2,$y2,$operation,$comment){ if($operation){ $root = $this->doc->firstChild; $rect = $this->doc->createElement('rect_area'); $rect->setAttribute('rect',"($x1,$y1,$x2,$y2)"); $rect->appendChild($this->doc->createComment('Area Context')); $root->appendChild($rect); self::addXMLString($operation,$rect,1); } } /** * 操作XML引数を解釈してDOMオブジェクトにノードを追加する。 * (再起処理の為ループに陥らないように50以上のネスト構造は中断) * @access private * @param string $string 操作XML引数文字列 * @param string $node   親ノード * @param string $count   累積呼び出し数 */ private function addXMLString($string,$node,$count=0){ // print "call get string $count
\n"; if($count > 50){ return FALSE; } $str_array = self::separatePipe($string); foreach($str_array as $str){ // print "loop for $str\n
\n"; list($parent,$child) = self::getElement($str); // print "$parent\n
\n"; if($parent){ // print "exec parent : $parent($count)\n
\n"; // $this->XMLString .= "$parent($count)\n"; if(eregi("([^=]+)=(.+)$",$parent,$pat)){ $tag = $pat[1]; $attr = $pat[2]; }else{ $tag = $parent; } switch ($tag) { case mouse: $new_node = $this->doc->createElement('mouseclick_event'); $new_node->appendChild($this->doc->createComment('Event Context')); $node->appendChild($new_node); break; case link: $new_node = $this->doc->createElement('link_operation'); $new_node->setAttribute('url',$attr); $new_node->setAttribute('target','_blank'); $node->appendChild($new_node); break; case menu: $new_node = $this->doc->createElement('menu_operation'); $new_node->setAttribute('title',$attr); $new_node->appendChild($this->doc->createComment('Menu Context')); $node->appendChild($new_node); break; case item: $new_node = $this->doc->createElement('menu_item'); $new_node->setAttribute('caption',$attr); $new_node->appendChild($this->doc->createComment('Event Context')); $node->appendChild($new_node); break; case sub: $new_node = $this->doc->createElement('suboperation'); $new_node->setAttribute('url',$attr); $node->appendChild($new_node); break; default: $new_node = $node; break; } if($child){ $arg_count = $count+1; self::addXMLString($child,$new_node,$arg_count); } // list($parent,$child) = getElement($child); } } } /** * 操作引数文字列から要素を取り出す * @access private * @param string $string 操作XML引数文字列 * @return array 親要素、子要素 */ private function getElement($string){ if(eregi("^([^(]+)\((.+)\)$",$string,$pat)){ $parent = $pat[1]; $child = $pat[2]; }else{ $parent = $string; $child = ''; } return array($parent,$child); } /** * 子要素が並列記述である場合に分離して配列で返す * @access private * @param string $string 子要素 * @return array 子要素の配列 */ private function separatePipe($string){ $array = array(); $flg = 1; $separated = ''; $remain = ''; $count = 0; $test_count = 0; while($string){ if($flg){ if(eregi("^([^()|]+)\|(.*)$",$string,$pat)){ $separated = $pat[1]; $string = $pat[2]; array_push($array,$separated); $separated = ''; $flg = 1; }elseif(eregi("^([^(]+\()(.+)$",$string,$pat)){ $separated = $pat[1]; $string = $pat[2]; $flg = 0; $count++; }else{ $separated = $string; array_push($array,$separated); $string =''; $flg = 1; } }else{ if(eregi("^([^()]+\()(.+)$",$string,$pat)){ $separated .= $pat[1]; $string = $pat[2]; $count++; }elseif(eregi("^([^()]*\))(.*)$",$string,$pat)){ $separated .= $pat[1]; $string = $pat[2]; $count--; if($count == 0){ array_push($array,$separated); $separated = ''; if(!($string)){ }elseif(eregi("^\|(.*)$",$string,$pat)){ $string = $pat[1]; }else{ } $flg = 1; } } } $test_count++; if($test_count > 100){ break; } } return $array; } /** * XMLファイルを出力する * @access public */ public function outputXML(){ $fp = fopen($this->xmlfile,'w'); flock($fp,LOCK_EX); fwrite($fp,$this->doc->saveXML()); fwrite($fp,"\n"); // fwrite($fp,$this->XMLString); flock($fp,LOCK_UN); fclose($fp); } /** * XMLファイルを標準出力に出力する * @access public */ public function outputXMLStandard(){ if($this->doc){ header("Content-Type: text/xml; charset=EUC-JP"); print $this->doc->saveXML(); print "\n"; } } /** * XMLファイルからDOMオブジェクトを取得 * @access public * @param string $domfile オブジェクトファイル名 */ public function getDOMObjectFromXMLFile($xmlfile='',$limit=60){ if(!($xmlfile) && $this->xmlfile){ $xmlfile = $this->xmlfile; }else{ return FALSE; } //ファイル読み込みリミット秒設定 if($limit <= 0){ $limit = 60; } //wait値 $wait = 10; //XMLファイルをファイルから読み込む //読み込めなかった場合は$wait秒sleep($limit秒まで) for($i=0;$i<$limit;$i+=$wait){ if($fpdom = fopen($xmlfile,'r')){ while($str = fgets($fpdom)){ $line .= $str; } break; }else{ sleep($wait); } } //読み込んだファイルをアンシリアライズしてDOMオブジェクトに格納 if($line){ $this->doc = DOMDocument::loadXML($line); }else{ return FALSE; } } /** * DOMオブジェクトをXML化してキャッシュ出力 * @access public * @param string $cache_id キャッシュID * @param int $expire_sec キャッシュ有効時間(秒) * @param int $cleaning_times キャッシュ自動クリーニング間隔(キャッシュ作成X回に1回) */ public function cacheDOMObject($cache_id,$expire_sec=3600,$cleaning_times=0){ //キャッシュIDがNULL if(!($cache_id)){ return FALSE; } //DOMオブジェクトをXML化する $line = $this->doc->saveXML(); //とりあえずXML出力ディレクトリにキャッシュ $cache_dir = dirname($this->xmlfile)."/"; // print $cache_dir; //キャッシュ設定 if($expire_sec < 0){ $expire_sec = 3600; } if($cleaning_times < 0){ $cleaning_times = 20; } $cache_param = array("cacheDir"=>$cache_dir,"cacheTime"=>$expire_sec,"automaticCleaningFactor"=>$cleaning_times); //キャッシュインスタンス作成 $myCache = new Cache_Lite($cache_param); //XMLデータをファイルに出力 // $cache_id = 'id for test'; $myCache->save($line,$cache_id); } /** * キャッシュされたXMLデータを読み込んでDOMオブジェクトに格納 * @access public * @param string $cache_id キャッシュID * @param int $limit 最大読み込み待ち時間 * @param int $wait 再読み込み間隔 */ public function readDOMObjectCache($cache_id,$limit=60,$wait=10){ //キャッシュIDがNULL if(!($cache_id)){ return FALSE; } //とりあえずXML出力ディレクトリにキャッシュ $cache_dir = dirname($this->xmlfile)."/"; // print $cache_dir; //キャッシュ設定 $expire_sec = 60; $cleaning_times = 20; $cache_param = array("cacheDir"=>$cache_dir,"cacheTime"=>$expire_sec,"automaticCleaningFactor"=>$cleaning_times); $myCache = new Cache_Lite($cache_param); //XMLキャッシュファイルを読み込み // $cache_id = 'id for test'; //ファイル読み込みリミット秒設定 if($limit <= 0){ $limit = 60; } if($wait <= 0){ $wait = 10; } //キャッシュファイルから読み込む //読み込めなかった場合は$wait秒waitしてから再実行($limit秒まで) for($i=0;$i<$limit;$i+=$wait){ if($line = $myCache->get($cache_id)){ //DOMオブジェクトに格納 $this->doc = DOMDocument::loadXML($line); break; }else{ sleep($wait); } } } } ?>