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);
}
}
}
}
?>