From 019017120703425fc92f0fae75d7c340b935a237 Mon Sep 17 00:00:00 2001 From: wlx Date: Thu, 18 Jun 2015 20:09:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=8E=9F=E5=9E=8B=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ISO19115-cn.php | 655 ++++++++++++++++++++++++++++++++++++++++++++++++ ISO19115-en.php | 655 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 7 +- config.php | 11 + update.php | 128 ++++++++++ 5 files changed, 1454 insertions(+), 2 deletions(-) create mode 100755 ISO19115-cn.php create mode 100755 ISO19115-en.php create mode 100644 config.php create mode 100644 update.php diff --git a/ISO19115-cn.php b/ISO19115-cn.php new file mode 100755 index 0000000..42db362 --- /dev/null +++ b/ISO19115-cn.php @@ -0,0 +1,655 @@ +'discipline','place','stratum','temporal','theme'); + public $author; + public $error=array(); + public $xml; + + function __construct() + { + $this->dom = new DOMDocument(); + } + /** + * 从文件中读取元数据 + **/ + function load($file) + { + $this->dom->load($file); + $this->parse(); + } + /** + * 从字符串中读取元数据 + */ + function loadXML($str) + { + @$this->dom->loadXML($str); + $this->xml=$str; + $this->parse(); + } + /** + * 保存元数据到文件file中 + */ + function save($file) + { + return $this->dom->save($file); + } + /** + * 根据xml中的node保存为xml + **/ + function saveXML($node="") + { + return $this->dom->saveXML($node); + } + /** + * 根据UUID从数据库中提取元数据信息,不需要进行parse()操作 + **/ + function loadUUID($uuid) + { + } + function saveDB($db,$xml='') + { + if (!empty($xml)) $this->loadXML($xml); + //先删除已有元数据,然后再插入新数据 + $sql="delete from metadata where uuid=?"; + $db->query($sql,array($this->uuid)); + //删除所有未用到的responsible数据 + $sql="delete from responsible where id not in (select distinct(resid) from role)"; + $db->query($sql); + + //if (!empty($this->doi)) $row->doi=$this->doi; + //生成空白统计数据,可以转移到数据库端处理(todo) + try + { + $sql="insert into mdstat (uuid) values(?)"; + $db->query($sql,array($this->uuid)); + } catch (Exception $e) { + //do nothing. + //说明数据库中已存在该信息 + } + $dbmode=$db->getFetchMode(); + $db->setFetchMode(Zend_Db::FETCH_OBJ); + //save metadata into database + try { + if ($this->refDate) + { + $sql="insert into metadata (uuid,title,title_en,description,citation,suppinfo,fileformat,projection,datatype,filesize,ts_created, + timebegin,timeend,west,south,north,east,doi,ts_published) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + $db->query($sql,array($this->uuid,$this->resTitle,$this->resAltTitle,$this->idAbs,$this->citation,$this->suppinfo,$this->fileformat, + $this->projection,$this->datatype,$this->filesize,$this->mdDateSt,$this->timebegin,$this->timeend,$this->geoBox['w'], + $this->geoBox['s'],$this->geoBox['n'],$this->geoBox['e'],$this->doi,$this->refDate)); + } else { + $sql="insert into metadata (uuid,title,title_en,description,citation,suppinfo,fileformat,projection,datatype,filesize,ts_created, + timebegin,timeend,west,south,north,east,doi) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + $db->query($sql,array($this->uuid,$this->resTitle,$this->resAltTitle,$this->idAbs,$this->citation,$this->suppinfo,$this->fileformat, + $this->projection,$this->datatype,$this->filesize,$this->mdDateSt,$this->timebegin,$this->timeend,$this->geoBox['w'], + $this->geoBox['s'],$this->geoBox['n'],$this->geoBox['e'],$this->doi)); + } + $id=$db->lastInsertId('metadata','id'); + //处理在线资源 + if ($this->onlineresource) foreach($this->onlineresource as $resource) + { + $sql="insert into onlineresource (uuid,linkage,protocol,name,description) values(?,?,?,?,?)"; + if (!isset($resource['name'])) $resource['name']=''; + if (!isset($resource['description'])) $resource['description']=''; + $db->query($sql,array($this->uuid,$resource['linkage'],$resource['protocol'],$resource['name'],$resource['description'])); + } + //处理缩略图 + if (!empty($this->thumbnail)) { + $sql="insert into thumbnail (id,data,filetype) values(?,?,?)"; + $db->query($sql,array($id,$this->thumbnail,'jpg')); + } elseif ($this->graph) { + //$trow->data=$this->graph['data']; + $sql="select id as gid from geonetworkmetadata where uuid=?"; + $r=$db->fetchRow($sql,array($this->uuid)); + if ($r) + { + $geonetwork='http://'.$_SERVER['HTTP_HOST'].'/geonetwork/'; + $thumb=base64_encode(file_get_contents($geonetwork.'srv/cn/resources.get?access=public&id='.$r->gid.'&fname='.urlencode($this->graph['filename']))); + $sql="insert into thumbnail (id,data,filetype,filedesc,filename) values(?,?,?,?,?)"; + $db->query($sql,array($id,$thumb,$this->graph['filetype'],$this->graph['filedesc'],$this->graph['filename'])); + } + } + //处理关键词 + //1:N relation + foreach($this->keyword as $keytype=>$keys) + { + foreach($keys as $key) + { + $sql="insert into keyword (id,keyword,keytype) values(?,?,?)"; + try { + $db->query($sql,array($id,$key,$keytype)); + } catch(Exception $e) { + //忽略关键词错误 + } + } + } + //处理数据集序列 + //M:N relation + if ($this->datasetSeries) foreach($this->datasetSeries as $ds) if (!empty($ds['seriesName'])) + { + $sql="select id from series where name=?"; + $sth=$db->prepare($sql); + $sth->execute(array($ds['seriesName'])); + $trow=$sth->fetch(); + if ($trow) + $sid=$trow->id; + else { + $sql="insert into series (name) values(?)"; + $db->query($sql,array($ds['seriesName'])); + $sid=$db->lastInsertId('series','id'); + } + $sql="insert into dataseries (id,sid) values(?,?)"; + $db->query($sql,array($id,$sid)); + } + //处理数据分类 + foreach($this->tpCat as $cat){ + if (is_numeric($cat)) { + $sql="insert into category (id,code) values(?,?)"; + $db->query($sql,array($id,(int)$cat)); + } else { + //是字符串,geonetwork会采用这种模式 + //从categorycode表中查找其对应的code + $sql="insert into category (id,code) select ?,code from categorycode where name=?"; + $db->query($sql,array($id, trim($cat))); + } + } + //处理联系人信息 + //先查询再进行处理 + //若用户信息发生变化,则存在问题 + //无法保证数据的更新状态 + foreach($this->author as $au) + { + $inds=explode(";",$au['individual']); + foreach($inds as $ind) + { + $sql="select id from responsible where individual=? and organisation=?"; + $row=$db->fetchRow($sql,array(trim($ind),trim($au['organisation']))); + if (!$row) + { + $sql="insert into responsible (individual,organisation,position,delivery,phone,email,city,country,administrative,postal) values(?,?,?,?,?,?,?,?,?,?)"; + $db->query($sql,array(trim($ind),trim($au['organisation']),trim($au['position']),trim($au['delivery']),trim($au['phone']),trim($au['email']),trim($au['city']),trim($au['country']),trim($au['administrative']),trim($au['postal']))); + } elseif (count($inds)==1) { + //deal email address + if (($au['email']) && empty($row->email)) + { + $sql="update responsible set email=? where id=?"; + $db->query($sql,array(trim($au['email']),$row->id)); + } + } + $sql="select id from responsible where individual=? and organisation=?"; + $row=$db->fetchRow($sql,array(trim($ind),trim($au['organisation']))); + if ($row->id>0) + { + $sql="insert into role (resid,uuid,role) values(?,?,?)"; + $db->query($sql,array($row->id,$this->uuid,trim($au['role']))); + } + } + } + //处理数据限制信息 + foreach($this->limits as $uselimit) + { + $sql="select id from uselimit where uselimit=?"; + $row=$db->fetchRow($sql,array($uselimit)); + if (!$row) + { + $sql="insert into uselimit (uselimit) values (?)"; + $db->query($sql,array($uselimit)); + } + $sql="select id from uselimit where uselimit=?"; + $row=$db->fetchRow($sql,array($uselimit)); + if ($row) + { + $sql="insert into mdlimit (uuid,lid) values(?,?)"; + $db->query($sql,array($this->uuid,$row->id)); + } + } + $this->save("../data/import/$this->uuid.xml"); + //处理XML入库 + if (!empty($xml)) $this->xml=$xml; + $sql="insert into xml (id,data) values(?,?)"; + $db->query($sql,array($id,$this->xml)); + } catch (Exception $e) { + //数据重复插入,此处忽略所有错误 + print $this->uuid.' has error: '.$e->getMessage().'
'; + } + $db->setFetchMode($dbmode); + } + + //检查元数据的错误信息 + function validate() + { + //uuid + if (empty($this->uuid)) $this->error[]='错误:数据的UUID不能为空!'; + if (empty($this->resTitle)) $this->error[]='错误:数据标题不能为空!'; + if (!is_numeric($this->filesize)) $this->error[]='错误:数据的大小(传输量)必须为数字,单位为MB!'; + //空间范围 + if (!is_numeric($this->geoBox['w']) || !is_numeric($this->geoBox['e']) || !is_numeric($this->geoBox['s']) ||!is_numeric($this->geoBox['n'])) + $this->error[]='错误:数据的空间范围必须为数字格式的经纬度!'; + //时间范围 + if (!empty($this->timebegin) && !strtotime($this->timebegin)) + $this->error[]='错误:数据的开始时间格式不正确!'; + if (!empty($this->timeend) && !strtotime($this->timeend)) + $this->error[]='错误:数据的结束时间格式不正确!'; + //关键词不能有空白(即使关键词类型不一样) + foreach($this->keyword as $k1=>$keyt) + { + foreach($keyt as $k2=>$keyword) + { + if (empty($keyword)) $this->error[]='错误:数据的关键词不能为空!'; + } + } + //联系人必须有email地址? + //todo + + //建议有缩略图 + if (empty($this->graph)) $this->error[]='建议:请提供一张能反应或代表数据的图片(800像素以上)。'; + return count($this->error); + } + + function parse() + { + $this->resTitle=$this->dom->getElementsByTagName('resTitle')->item(0)->nodeValue; + @$this->resAltTitle=$this->dom->getElementsByTagName('resAltTitle')->item(0)->nodeValue; + $this->idAbs=$this->dom->getElementsByTagName('idAbs')->item(0)->nodeValue; + $this->mdFileID=$this->dom->getElementsByTagName('mdFileID')->item(0)->nodeValue; + $this->mdDateSt=$this->dom->getElementsByTagName('mdDateSt')->item(0)->nodeValue; + @$this->dataSetURI=$this->dom->getElementsByTagName('dataSetURI')->item(0)->nodeValue; + //引用说明 + @$this->citation=$this->dom->getElementsByTagName('otherCitDet')->item(0)->nodeValue; + //项目支持信息 + @$this->suppinfo=$this->dom->getElementsByTagName('suppInfo')->item(0)->nodeValue; + //DOI,自定义项 + $cittype=$this->dom->getElementsByTagName('citIdType')->item(0)->nodeValue; + if ($cittype=='DOI') + $this->doi=$this->dom->getElementsByTagName('citId')->item(0)->nodeValue; + //数据大小,以MB为单位 + @$this->filesize=$this->dom->getElementsByTagName('transSize')->item(0)->nodeValue; + //数据格式,可以多个,但此处只用一个? + @$this->fileformat=$this->dom->getElementsByTagName('formatName')->item(0)->nodeValue; + //投影类型,可以多个,但只选一个 + @$this->projection=$this->dom->getElementsByTagName('identCode')->item(0)->nodeValue; + //数据限制信息 + $limits=$this->dom->getElementsByTagName('useLimit'); + foreach($limits as $limit) + { + $this->limits[]=$limit->nodeValue; + } + //数据作者 + $authors=$this->dom->getElementsByTagName('citRespParty'); + foreach($authors as $k=>$author) + { + $this->author[$k]['individual']=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + $this->author[$k]['organisation']=$author->getElementsByTagName('rpOrgName')->item(0)->nodeValue; + @$this->author[$k]['position']=$author->getElementsByTagName('rpPosName')->item(0)->nodeValue; + @$this->author[$k]['delivery']=$author->getElementsByTagName('delPoint')->item(0)->nodeValue; + @$this->author[$k]['phone']=$author->getElementsByTagName('voiceNum')->item(0)->nodeValue; + @$this->author[$k]['email']=$author->getElementsByTagName('eMailAdd')->item(0)->nodeValue; + $this->author[$k]['postal']=$author->getElementsByTagName('postCode')->item(0)->nodeValue; + $this->author[$k]['city']=$author->getElementsByTagName('city')->item(0)->nodeValue; + $this->author[$k]['administrative']=$author->getElementsByTagName('adminArea')->item(0)->nodeValue; + $this->author[$k]['country']=$author->getElementsByTagName('country')->item(0)->nodeValue; + @$this->author[$k]['role']=$author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + $cnt=$k+1; + $authors=$this->dom->getElementsByTagName('mdContact'); + foreach($authors as $j=>$author) + { + $this->author[$cnt+$j]['individual']=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + $this->author[$cnt+$j]['organisation']=$author->getElementsByTagName('rpOrgName')->item(0)->nodeValue; + @$this->author[$cnt+$j]['position']=$author->getElementsByTagName('rpPosName')->item(0)->nodeValue; + $this->author[$cnt+$j]['delivery']=$author->getElementsByTagName('delPoint')->item(0)->nodeValue; + $this->author[$cnt+$j]['phone']=$author->getElementsByTagName('voiceNum')->item(0)->nodeValue; + $this->author[$cnt+$j]['email']=$author->getElementsByTagName('eMailAdd')->item(0)->nodeValue; + $this->author[$cnt+$j]['postal']=$author->getElementsByTagName('postCode')->item(0)->nodeValue; + $this->author[$cnt+$j]['city']=$author->getElementsByTagName('city')->item(0)->nodeValue; + $this->author[$cnt+$j]['administrative']=$author->getElementsByTagName('adminArea')->item(0)->nodeValue; + @$this->author[$cnt+$j]['country']=$author->getElementsByTagName('country')->item(0)->nodeValue; + $this->author[$cnt+$j]['role']=$author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + $cnt+=$j+1; + $authors=$this->dom->getElementsByTagName('distorCont'); + foreach($authors as $m=>$author) + { + $this->author[$cnt+$m]['individual']=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + $this->author[$cnt+$m]['organisation']=$author->getElementsByTagName('rpOrgName')->item(0)->nodeValue; + @$this->author[$cnt+$m]['position']=$author->getElementsByTagName('rpPosName')->item(0)->nodeValue; + $this->author[$cnt+$m]['delivery']=$author->getElementsByTagName('delPoint')->item(0)->nodeValue; + $this->author[$cnt+$m]['phone']=$author->getElementsByTagName('voiceNum')->item(0)->nodeValue; + $this->author[$cnt+$m]['email']=$author->getElementsByTagName('eMailAdd')->item(0)->nodeValue; + $this->author[$cnt+$m]['postal']=$author->getElementsByTagName('postCode')->item(0)->nodeValue; + $this->author[$cnt+$m]['city']=$author->getElementsByTagName('city')->item(0)->nodeValue; + $this->author[$cnt+$m]['administrative']=$author->getElementsByTagName('adminArea')->item(0)->nodeValue; + $this->author[$cnt+$m]['country']=$author->getElementsByTagName('country')->item(0)->nodeValue; + $this->author[$cnt+$m]['role']=$author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + $cnt+=$m+1; + $authors=$this->dom->getElementsByTagName('idPoC'); + foreach($authors as $m=>$author) + { + $this->author[$cnt+$m]['individual']=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + $this->author[$cnt+$m]['organisation']=$author->getElementsByTagName('rpOrgName')->item(0)->nodeValue; + @$this->author[$cnt+$m]['position']=$author->getElementsByTagName('rpPosName')->item(0)->nodeValue; + $this->author[$cnt+$m]['delivery']=$author->getElementsByTagName('delPoint')->item(0)->nodeValue; + $this->author[$cnt+$m]['phone']=$author->getElementsByTagName('voiceNum')->item(0)->nodeValue; + $this->author[$cnt+$m]['email']=$author->getElementsByTagName('eMailAdd')->item(0)->nodeValue; + $this->author[$cnt+$m]['postal']=$author->getElementsByTagName('postCode')->item(0)->nodeValue; + $this->author[$cnt+$m]['city']=$author->getElementsByTagName('city')->item(0)->nodeValue; + $this->author[$cnt+$m]['administrative']=$author->getElementsByTagName('adminArea')->item(0)->nodeValue; + $this->author[$cnt+$m]['country']=$author->getElementsByTagName('country')->item(0)->nodeValue; + $this->author[$cnt+$m]['role']=$author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + /* + foreach($authors as $author) + { + if($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="author") + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="originator" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="owner" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="processor" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="publisher" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="resourceProvider" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + } + } + */ + //数据类型,在线或离线 + $this->datatype=0; + $onlinesrc=$this->dom->getElementsByTagName('onLineSrc'); + foreach($onlinesrc as $k=>$src) + { + if ($src->getElementsByTagName('OnFunctCd')->item(0) + && $src->getElementsByTagName('OnFunctCd')->item(0)->hasAttributes() + && $src->getElementsByTagName('OnFunctCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="offlineAccess") + $this->datatype=1; + { + //在线资源 + $this->onlineresource[$k]['linkage']=$src->getElementsByTagName('linkage')->item(0)->nodeValue; + if ($src->getElementsByTagName('protocol')->item(0)) $this->onlineresource[$k]['protocol']=$src->getElementsByTagName('protocol')->item(0)->nodeValue; + if ($src->getElementsByTagName('orName')->item(0)) $this->onlineresource[$k]['name']=$src->getElementsByTagName('orName')->item(0)->nodeValue; + $this->onlineresource[$k]['description']=$src->getElementsByTagName('orDesc')->item(0)->nodeValue; + } + } + $cats=$this->dom->getElementsByTagName('tpCat'); + foreach($cats as $cat) + { + if ($cat->getElementsByTagName('TopicCatCd')->item(0)->hasAttributes()) + $this->tpCat[]=$cat->getElementsByTagName('TopicCatCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + @$this->bgFileName=$this->dom->getElementsByTagName('bgFileName')->item(0)->nodeValue; + $keywords=$this->dom->getElementsByTagName('descKeys');//Keywords? which one? + foreach($keywords as $keys) + { + if ($keys->getElementsByTagName('KeyTypCd')->item(0) && $keys->getElementsByTagName('KeyTypCd')->item(0)->hasAttributes()) + $k=$keys->getElementsByTagName('KeyTypCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + if (is_numeric($k)) + $kt=$this->keytypecode[(int)$k]; + else + $kt=$k; + //如果没有找到类别,则默认为主题关键词 + if (!$kt) $kt=$this->keytypecode[5]; + $ks=$keys->getElementsByTagName('keyword'); + foreach($ks as $key) + { + //处理特殊情况:多关键词输入在一起,用一些符号来分割,如分号等。 + $pos=strpos($key->nodeValue,';'); + if ($pos===false) + $this->keyword[$kt][]=$key->nodeValue; + else { + $str=explode(';',$key->nodeValue); + foreach($str as $s){ + $this->keyword[$kt][]=$s; + } + } + } + } + //resRefDate + $refdates=$this->dom->getElementsByTagName('resRefDate'); + foreach($refdates as $refdate) + { + if ($refdate->getElementsByTagName('DateTypCd')->item(0) && $refdate->getElementsByTagName('DateTypCd')->item(0)->hasAttributes() && $refdate->getElementsByTagName('DateTypCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="publication") + { + $this->refDate=$refdate->getElementsByTagName('refDate')->item(0)->nodeValue; + } + } + //in ISO 19115 draft. + $ds=$this->dom->getElementsByTagName('datasetSeries'); + foreach($ds as $k=>$dataset) + { + $this->datasetSeries[$k]['seriesName']=$dataset->getElementsByTagName('seriesName')->item(0)->nodeValue; + @$this->datasetSeries[$k]['issId']=$dataset->getElementsByTagName('issId')->item(0)->nodeValue; + @$this->datasetSeries[$k]['artPage']=$dataset->getElementsByTagName('artPage')->item(0)->nodeValue; + } + //unsure which one. + $ds=$this->dom->getElementsByTagName('Series'); + foreach($ds as $k=>$dataset) + { + $this->datasetSeries[$k]['seriesName']=$dataset->getElementsByTagName('Name')->item(0)->nodeValue; + $this->datasetSeries[$k]['issId']=$dataset->getElementsByTagName('issId')->item(0)->nodeValue; + $this->datasetSeries[$k]['artPage']=$dataset->getElementsByTagName('artPage')->item(0)->nodeValue; + } + //可能只适用于ESRI ARCCATELOG产生的元数据 + $extent=$this->dom->getElementsByTagName('geoBox'); + foreach($extent as $geo) + { + $this->geoBox['w']=$geo->getElementsByTagName('westBL')->item(0)->nodeValue; + $this->geoBox['s']=$geo->getElementsByTagName('southBL')->item(0)->nodeValue; + $this->geoBox['e']=$geo->getElementsByTagName('eastBL')->item(0)->nodeValue; + $this->geoBox['n']=$geo->getElementsByTagName('northBL')->item(0)->nodeValue; + } + //提取ESRI格式中的UUID + if (empty($this->uuid)) + { + @$this->uuid=$this->dom->getElementsByTagName('MetaID')->item(0)->nodeValue; + //剔除前后大括号 + $this->uuid=trim($this->uuid,'{'); + $this->uuid=trim($this->uuid,'}'); + } + //根据mdFileID来判断uuid + //如果mdFileID为uuid的组织形式,则进行提取 + if (strlen(trim($this->mdFileID))==36 && empty($this->uuid)) + $this->uuid=trim($this->mdFileID); + //仍然没有UUID信息,则创建一个 + if (empty($this->uuid)) + { + $this->uuid=new uuid(); + $this->uuid=$this->uuid->toString(); + //反馈回XML文件 + $mdfile=$this->dom->getElementsByTagName('mdFileID'); + if ($mdfile->length>0) { + $this->dom->getElementsByTagName('mdFileID')->item(0)->nodeValue=$this->uuid; + } else { + $mdfile=$this->dom->createElement('mdFileID', $this->uuid); + $this->dom->getElementsByTagName('Metadata')->item(0)->appendChild($mdfile); + } + } + //提取时间信息 + $tm_period=$this->dom->getElementsByTagName('TM_Period'); + foreach($tm_period as $period) + { + $this->timebegin=$period->getElementsByTagName('begin')->item(0)->nodeValue; + $this->timeend=$period->getElementsByTagName('end')->item(0)->nodeValue; + } + $tm_day=$this->dom->getElementsByTagName('TM_CalDate'); + foreach($tm_day as $day) + { + $this->timebegin=$day->getElementsByTagName('calDate')->item(0)->nodeValue; + } + //Todo:处理缩略图,限制为一个。 + //$thumb=$this->dom->getElementsByTagName('Thumbnail'); + $xpath = new DOMXPath($this->dom); + $query = '//metadata/Binary/Thumbnail/Data';//should be Metadata + $entries = $xpath->query($query); + if ($entries->length>0) + $this->thumbnail=$entries->item(0)->nodeValue; + else { + $query='//Metadata/Binary/Thumbnail/Data'; + $entries=$xpath->query($query); + @$this->thumbnail=$entries->item(0)->nodeValue; + } + //如果是从GEONETWORK获取,判断是否已有缩略图,获取最小的缩略图 + $graphs=$this->dom->getElementsByTagName('graphOver'); + foreach ($graphs as $g) + { + if ($g->getElementsByTagName('bgFileDesc')->item(0)->nodeValue=='thumbnail') { + $this->graph['filename']=$g->getElementsByTagName('bgFileName')->item(0)->nodeValue; + $this->graph['filedesc']='thumbnail'; + $this->graph['filetype']=$g->getElementsByTagName('bgFileType')->item(0)->nodeValue; + } + } + } +} +?> \ No newline at end of file diff --git a/ISO19115-en.php b/ISO19115-en.php new file mode 100755 index 0000000..d5b782c --- /dev/null +++ b/ISO19115-en.php @@ -0,0 +1,655 @@ +'discipline','place','stratum','temporal','theme'); + public $author; + public $error=array(); + public $xml; + + function __construct() + { + $this->dom = new DOMDocument(); + } + /** + * 从文件中读取元数据 + **/ + function load($file) + { + $this->dom->load($file); + $this->parse(); + } + /** + * 从字符串中读取元数据 + */ + function loadXML($str) + { + @$this->dom->loadXML($str); + $this->xml=$str; + $this->parse(); + } + /** + * 保存元数据到文件file中 + */ + function save($file) + { + return $this->dom->save($file); + } + /** + * 根据xml中的node保存为xml + **/ + function saveXML($node="") + { + return $this->dom->saveXML($node); + } + /** + * 根据UUID从数据库中提取元数据信息,不需要进行parse()操作 + **/ + function loadUUID($uuid) + { + } + function saveDB($db,$xml='') + { + if (!empty($xml)) $this->loadXML($xml); + //先删除已有元数据,然后再插入新数据 + $sql="delete from en.metadata where uuid=?"; + $db->query($sql,array($this->uuid)); + //删除所有未用到的responsible数据 + $sql="delete from en.responsible where id not in (select distinct(resid) from role)"; + pg_query($db,$sql); + + //if (!empty($this->doi)) $row->doi=$this->doi; + //生成空白统计数据,可以转移到数据库端处理(todo) + try + { + //$sql="insert into mdstat (uuid) values(?)"; + //$db->query($sql,array($this->uuid)); + } catch (Exception $e) { + //do nothing. + //说明数据库中已存在该信息 + } + $dbmode=$db->getFetchMode(); + $db->setFetchMode(Zend_Db::FETCH_OBJ); + //save metadata into database + try { + if ($this->refDate) + { + $sql="insert into en.metadata (uuid,title,title_en,description,citation,suppinfo,fileformat,projection,datatype,filesize,ts_created, + timebegin,timeend,west,south,north,east,doi,ts_published) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + $db->query($sql,array($this->uuid,$this->resTitle,$this->resAltTitle,$this->idAbs,$this->citation,$this->suppinfo,$this->fileformat, + $this->projection,$this->datatype,$this->filesize,$this->mdDateSt,$this->timebegin,$this->timeend,$this->geoBox['w'], + $this->geoBox['s'],$this->geoBox['n'],$this->geoBox['e'],$this->doi,$this->refDate)); + } else { + $sql="insert into en.metadata (uuid,title,title_en,description,citation,suppinfo,fileformat,projection,datatype,filesize,ts_created, + timebegin,timeend,west,south,north,east,doi) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + $db->query($sql,array($this->uuid,$this->resTitle,$this->resAltTitle,$this->idAbs,$this->citation,$this->suppinfo,$this->fileformat, + $this->projection,$this->datatype,$this->filesize,$this->mdDateSt,$this->timebegin,$this->timeend,$this->geoBox['w'], + $this->geoBox['s'],$this->geoBox['n'],$this->geoBox['e'],$this->doi)); + } + $id=$db->lastInsertId('en.metadata','id'); + //处理在线资源 + if ($this->onlineresource) foreach($this->onlineresource as $resource) + { + $sql="insert into en.onlineresource (uuid,linkage,protocol,name,description) values(?,?,?,?,?)"; + if (!isset($resource['name'])) $resource['name']=''; + if (!isset($resource['description'])) $resource['description']=''; + $db->query($sql,array($this->uuid,$resource['linkage'],$resource['protocol'],$resource['name'],$resource['description'])); + } + //处理缩略图 + if (!empty($this->thumbnail)) { + $sql="insert into en.thumbnail (id,data,filetype) values(?,?,?)"; + $db->query($sql,array($id,$this->thumbnail,'jpg')); + } elseif ($this->graph) { + //$trow->data=$this->graph['data']; + $sql="select id as gid from en.geonetworkmetadata where uuid=?"; + $r=$db->fetchRow($sql,array($this->uuid)); + if ($r) + { + $geonetwork='http://'.$_SERVER['HTTP_HOST'].'/geonetwork/'; + $thumb=base64_encode(file_get_contents($geonetwork.'srv/cn/resources.get?access=public&id='.$r->gid.'&fname='.urlencode($this->graph['filename']))); + $sql="insert into en.thumbnail (id,data,filetype,filedesc,filename) values(?,?,?,?,?)"; + $db->query($sql,array($id,$thumb,$this->graph['filetype'],$this->graph['filedesc'],$this->graph['filename'])); + } + } + //处理关键词 + //1:N relation + foreach($this->keyword as $keytype=>$keys) + { + foreach($keys as $key) + { + $sql="insert into en.keyword (id,keyword,keytype) values(?,?,?)"; + try { + $db->query($sql,array($id,$key,$keytype)); + } catch(Exception $e) { + //忽略关键词错误 + } + } + } + //处理数据集序列 + //M:N relation + if ($this->datasetSeries) foreach($this->datasetSeries as $ds) if (!empty($ds['seriesName'])) + { + $sql="select id from en.series where name=?"; + $sth=$db->prepare($sql); + $sth->execute(array($ds['seriesName'])); + $trow=$sth->fetch(); + if ($trow) + $sid=$trow->id; + else { + $sql="insert into en.series (name) values(?)"; + $db->query($sql,array($ds['seriesName'])); + $sid=$db->lastInsertId('en.series','id'); + } + $sql="insert into en.dataseries (id,sid) values(?,?)"; + $db->query($sql,array($id,$sid)); + } + //处理数据分类 + foreach($this->tpCat as $cat){ + if (is_numeric($cat)) { + $sql="insert into en.category (id,code) values(?,?)"; + $db->query($sql,array($id,(int)$cat)); + } else { + //是字符串,geonetwork会采用这种模式 + //从categorycode表中查找其对应的code + $sql="insert into en.category (id,code) select ?,code from categorycode where name=?"; + $db->query($sql,array($id, trim($cat))); + } + } + //处理联系人信息 + //先查询再进行处理 + //若用户信息发生变化,则存在问题 + //无法保证数据的更新状态 + foreach($this->author as $au) + { + $inds=explode(";",$au['individual']); + foreach($inds as $ind) + { + $sql="select id from en.responsible where individual=? and organisation=?"; + $row=$db->fetchRow($sql,array(trim($ind),trim($au['organisation']))); + if (!$row) + { + $sql="insert into en.responsible (individual,organisation,position,delivery,phone,email,city,country,administrative,postal) values(?,?,?,?,?,?,?,?,?,?)"; + $db->query($sql,array(trim($ind),trim($au['organisation']),trim($au['position']),trim($au['delivery']),trim($au['phone']),trim($au['email']),trim($au['city']),trim($au['country']),trim($au['administrative']),trim($au['postal']))); + } elseif (count($inds)==1) { + //deal email address + if (($au['email']) && empty($row->email)) + { + $sql="update en.responsible set email=? where id=?"; + $db->query($sql,array(trim($au['email']),$row->id)); + } + } + $sql="select id from en.responsible where individual=? and organisation=?"; + $row=$db->fetchRow($sql,array(trim($ind),trim($au['organisation']))); + if ($row->id>0) + { + $sql="insert into en.role (resid,uuid,role) values(?,?,?)"; + $db->query($sql,array($row->id,$this->uuid,trim($au['role']))); + } + } + } + //处理数据限制信息 + foreach($this->limits as $uselimit) + { + $sql="select id from en.uselimit where uselimit=?"; + $row=$db->fetchRow($sql,array($uselimit)); + if (!$row) + { + $sql="insert into en.uselimit (uselimit) values (?)"; + $db->query($sql,array($uselimit)); + } + $sql="select id from en.uselimit where uselimit=?"; + $row=$db->fetchRow($sql,array($uselimit)); + if ($row) + { + $sql="insert into en.mdlimit (uuid,lid) values(?,?)"; + $db->query($sql,array($this->uuid,$row->id)); + } + } + $this->save("../data/import/$this->uuid.xml"); + //处理XML入库 + if (!empty($xml)) $this->xml=$xml; + $sql="insert into en.xml (id,data) values(?,?)"; + $db->query($sql,array($id,$this->xml)); + } catch (Exception $e) { + //数据重复插入,此处忽略所有错误 + print $this->uuid.' has error: '.$e->getMessage().'
'; + } + $db->setFetchMode($dbmode); + } + + //检查元数据的错误信息 + function validate() + { + //uuid + if (empty($this->uuid)) $this->error[]='错误:数据的UUID不能为空!'; + if (empty($this->resTitle)) $this->error[]='错误:数据标题不能为空!'; + if (!is_numeric($this->filesize)) $this->error[]='错误:数据的大小(传输量)必须为数字,单位为MB!'; + //空间范围 + if (!is_numeric($this->geoBox['w']) || !is_numeric($this->geoBox['e']) || !is_numeric($this->geoBox['s']) ||!is_numeric($this->geoBox['n'])) + $this->error[]='错误:数据的空间范围必须为数字格式的经纬度!'; + //时间范围 + if (!empty($this->timebegin) && !strtotime($this->timebegin)) + $this->error[]='错误:数据的开始时间格式不正确!'; + if (!empty($this->timeend) && !strtotime($this->timeend)) + $this->error[]='错误:数据的结束时间格式不正确!'; + //关键词不能有空白(即使关键词类型不一样) + foreach($this->keyword as $k1=>$keyt) + { + foreach($keyt as $k2=>$keyword) + { + if (empty($keyword)) $this->error[]='错误:数据的关键词不能为空!'; + } + } + //联系人必须有email地址? + //todo + + //建议有缩略图 + if (empty($this->graph)) $this->error[]='建议:请提供一张能反应或代表数据的图片(800像素以上)。'; + return count($this->error); + } + + function parse() + { + $this->resTitle=$this->dom->getElementsByTagName('resTitle')->item(0)->nodeValue; + @$this->resAltTitle=$this->dom->getElementsByTagName('resAltTitle')->item(0)->nodeValue; + $this->idAbs=$this->dom->getElementsByTagName('idAbs')->item(0)->nodeValue; + $this->mdFileID=$this->dom->getElementsByTagName('mdFileID')->item(0)->nodeValue; + $this->mdDateSt=$this->dom->getElementsByTagName('mdDateSt')->item(0)->nodeValue; + @$this->dataSetURI=$this->dom->getElementsByTagName('dataSetURI')->item(0)->nodeValue; + //引用说明 + @$this->citation=$this->dom->getElementsByTagName('otherCitDet')->item(0)->nodeValue; + //项目支持信息 + @$this->suppinfo=$this->dom->getElementsByTagName('suppInfo')->item(0)->nodeValue; + //DOI,自定义项 + $cittype=$this->dom->getElementsByTagName('citIdType')->item(0)->nodeValue; + if ($cittype=='DOI') + $this->doi=$this->dom->getElementsByTagName('citId')->item(0)->nodeValue; + //数据大小,以MB为单位 + @$this->filesize=$this->dom->getElementsByTagName('transSize')->item(0)->nodeValue; + //数据格式,可以多个,但此处只用一个? + @$this->fileformat=$this->dom->getElementsByTagName('formatName')->item(0)->nodeValue; + //投影类型,可以多个,但只选一个 + @$this->projection=$this->dom->getElementsByTagName('identCode')->item(0)->nodeValue; + //数据限制信息 + $limits=$this->dom->getElementsByTagName('useLimit'); + foreach($limits as $limit) + { + $this->limits[]=$limit->nodeValue; + } + //数据作者 + $authors=$this->dom->getElementsByTagName('citRespParty'); + foreach($authors as $k=>$author) + { + $this->author[$k]['individual']=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + $this->author[$k]['organisation']=$author->getElementsByTagName('rpOrgName')->item(0)->nodeValue; + @$this->author[$k]['position']=$author->getElementsByTagName('rpPosName')->item(0)->nodeValue; + @$this->author[$k]['delivery']=$author->getElementsByTagName('delPoint')->item(0)->nodeValue; + @$this->author[$k]['phone']=$author->getElementsByTagName('voiceNum')->item(0)->nodeValue; + @$this->author[$k]['email']=$author->getElementsByTagName('eMailAdd')->item(0)->nodeValue; + $this->author[$k]['postal']=$author->getElementsByTagName('postCode')->item(0)->nodeValue; + $this->author[$k]['city']=$author->getElementsByTagName('city')->item(0)->nodeValue; + $this->author[$k]['administrative']=$author->getElementsByTagName('adminArea')->item(0)->nodeValue; + @$this->author[$k]['country']=$author->getElementsByTagName('country')->item(0)->nodeValue; + @$this->author[$k]['role']=$author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + $cnt=$k+1; + $authors=$this->dom->getElementsByTagName('mdContact'); + foreach($authors as $j=>$author) + { + $this->author[$cnt+$j]['individual']=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + $this->author[$cnt+$j]['organisation']=$author->getElementsByTagName('rpOrgName')->item(0)->nodeValue; + @$this->author[$cnt+$j]['position']=$author->getElementsByTagName('rpPosName')->item(0)->nodeValue; + @$this->author[$cnt+$j]['delivery']=$author->getElementsByTagName('delPoint')->item(0)->nodeValue; + @$this->author[$cnt+$j]['phone']=$author->getElementsByTagName('voiceNum')->item(0)->nodeValue; + @$this->author[$cnt+$j]['email']=$author->getElementsByTagName('eMailAdd')->item(0)->nodeValue; + $this->author[$cnt+$j]['postal']=$author->getElementsByTagName('postCode')->item(0)->nodeValue; + $this->author[$cnt+$j]['city']=$author->getElementsByTagName('city')->item(0)->nodeValue; + $this->author[$cnt+$j]['administrative']=$author->getElementsByTagName('adminArea')->item(0)->nodeValue; + @$this->author[$cnt+$j]['country']=$author->getElementsByTagName('country')->item(0)->nodeValue; + $this->author[$cnt+$j]['role']=$author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + $cnt+=$j+1; + $authors=$this->dom->getElementsByTagName('distorCont'); + foreach($authors as $m=>$author) + { + $this->author[$cnt+$m]['individual']=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + $this->author[$cnt+$m]['organisation']=$author->getElementsByTagName('rpOrgName')->item(0)->nodeValue; + @$this->author[$cnt+$m]['position']=$author->getElementsByTagName('rpPosName')->item(0)->nodeValue; + @$this->author[$cnt+$m]['delivery']=$author->getElementsByTagName('delPoint')->item(0)->nodeValue; + @$this->author[$cnt+$m]['phone']=$author->getElementsByTagName('voiceNum')->item(0)->nodeValue; + @$this->author[$cnt+$m]['email']=$author->getElementsByTagName('eMailAdd')->item(0)->nodeValue; + $this->author[$cnt+$m]['postal']=$author->getElementsByTagName('postCode')->item(0)->nodeValue; + $this->author[$cnt+$m]['city']=$author->getElementsByTagName('city')->item(0)->nodeValue; + $this->author[$cnt+$m]['administrative']=$author->getElementsByTagName('adminArea')->item(0)->nodeValue; + @$this->author[$cnt+$m]['country']=$author->getElementsByTagName('country')->item(0)->nodeValue; + $this->author[$cnt+$m]['role']=$author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + $cnt+=$m+1; + $authors=$this->dom->getElementsByTagName('idPoC'); + foreach($authors as $m=>$author) + { + $this->author[$cnt+$m]['individual']=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + $this->author[$cnt+$m]['organisation']=$author->getElementsByTagName('rpOrgName')->item(0)->nodeValue; + @$this->author[$cnt+$m]['position']=$author->getElementsByTagName('rpPosName')->item(0)->nodeValue; + $this->author[$cnt+$m]['delivery']=$author->getElementsByTagName('delPoint')->item(0)->nodeValue; + $this->author[$cnt+$m]['phone']=$author->getElementsByTagName('voiceNum')->item(0)->nodeValue; + $this->author[$cnt+$m]['email']=$author->getElementsByTagName('eMailAdd')->item(0)->nodeValue; + $this->author[$cnt+$m]['postal']=$author->getElementsByTagName('postCode')->item(0)->nodeValue; + $this->author[$cnt+$m]['city']=$author->getElementsByTagName('city')->item(0)->nodeValue; + $this->author[$cnt+$m]['administrative']=$author->getElementsByTagName('adminArea')->item(0)->nodeValue; + $this->author[$cnt+$m]['country']=$author->getElementsByTagName('country')->item(0)->nodeValue; + $this->author[$cnt+$m]['role']=$author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + /* + foreach($authors as $author) + { + if($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="author") + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="originator" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="owner" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="processor" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="publisher" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + }elseif ($author->getElementsByTagName('rpIndName')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0) && + $author->getElementsByTagName('RoleCd')->item(0)->hasAttributes() && + $author->getElementsByTagName('RoleCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="resourceProvider" ) + { + $this->author=$author->getElementsByTagName('rpIndName')->item(0)->nodeValue; + break; + } + } + */ + //数据类型,在线或离线 + $this->datatype=0; + $onlinesrc=$this->dom->getElementsByTagName('onLineSrc'); + foreach($onlinesrc as $k=>$src) + { + if ($src->getElementsByTagName('OnFunctCd')->item(0) + && $src->getElementsByTagName('OnFunctCd')->item(0)->hasAttributes() + && $src->getElementsByTagName('OnFunctCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="offlineAccess") + $this->datatype=1; + { + //在线资源 + $this->onlineresource[$k]['linkage']=$src->getElementsByTagName('linkage')->item(0)->nodeValue; + if ($src->getElementsByTagName('protocol')->item(0)) $this->onlineresource[$k]['protocol']=$src->getElementsByTagName('protocol')->item(0)->nodeValue; + if ($src->getElementsByTagName('orName')->item(0)) $this->onlineresource[$k]['name']=$src->getElementsByTagName('orName')->item(0)->nodeValue; + $this->onlineresource[$k]['description']=$src->getElementsByTagName('orDesc')->item(0)->nodeValue; + } + } + $cats=$this->dom->getElementsByTagName('tpCat'); + foreach($cats as $cat) + { + if ($cat->getElementsByTagName('TopicCatCd')->item(0)->hasAttributes()) + $this->tpCat[]=$cat->getElementsByTagName('TopicCatCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + } + @$this->bgFileName=$this->dom->getElementsByTagName('bgFileName')->item(0)->nodeValue; + $keywords=$this->dom->getElementsByTagName('descKeys');//Keywords? which one? + foreach($keywords as $keys) + { + if ($keys->getElementsByTagName('KeyTypCd')->item(0) && $keys->getElementsByTagName('KeyTypCd')->item(0)->hasAttributes()) + $k=$keys->getElementsByTagName('KeyTypCd')->item(0)->attributes->getNamedItem('value')->nodeValue; + if (is_numeric($k)) + $kt=$this->keytypecode[(int)$k]; + else + $kt=$k; + //如果没有找到类别,则默认为主题关键词 + if (!$kt) $kt=$this->keytypecode[5]; + $ks=$keys->getElementsByTagName('keyword'); + foreach($ks as $key) + { + //处理特殊情况:多关键词输入在一起,用一些符号来分割,如分号等。 + $pos=strpos($key->nodeValue,';'); + if ($pos===false) + $this->keyword[$kt][]=$key->nodeValue; + else { + $str=explode(';',$key->nodeValue); + foreach($str as $s){ + $this->keyword[$kt][]=$s; + } + } + } + } + //resRefDate + $refdates=$this->dom->getElementsByTagName('resRefDate'); + foreach($refdates as $refdate) + { + if ($refdate->getElementsByTagName('DateTypCd')->item(0) && $refdate->getElementsByTagName('DateTypCd')->item(0)->hasAttributes() && $refdate->getElementsByTagName('DateTypCd')->item(0)->attributes->getNamedItem('value')->nodeValue=="publication") + { + $this->refDate=$refdate->getElementsByTagName('refDate')->item(0)->nodeValue; + } + } + //in ISO 19115 draft. + $ds=$this->dom->getElementsByTagName('datasetSeries'); + foreach($ds as $k=>$dataset) + { + $this->datasetSeries[$k]['seriesName']=$dataset->getElementsByTagName('seriesName')->item(0)->nodeValue; + @$this->datasetSeries[$k]['issId']=$dataset->getElementsByTagName('issId')->item(0)->nodeValue; + @$this->datasetSeries[$k]['artPage']=$dataset->getElementsByTagName('artPage')->item(0)->nodeValue; + } + //unsure which one. + $ds=$this->dom->getElementsByTagName('Series'); + foreach($ds as $k=>$dataset) + { + $this->datasetSeries[$k]['seriesName']=$dataset->getElementsByTagName('Name')->item(0)->nodeValue; + $this->datasetSeries[$k]['issId']=$dataset->getElementsByTagName('issId')->item(0)->nodeValue; + $this->datasetSeries[$k]['artPage']=$dataset->getElementsByTagName('artPage')->item(0)->nodeValue; + } + //可能只适用于ESRI ARCCATELOG产生的元数据 + $extent=$this->dom->getElementsByTagName('geoBox'); + foreach($extent as $geo) + { + $this->geoBox['w']=$geo->getElementsByTagName('westBL')->item(0)->nodeValue; + $this->geoBox['s']=$geo->getElementsByTagName('southBL')->item(0)->nodeValue; + $this->geoBox['e']=$geo->getElementsByTagName('eastBL')->item(0)->nodeValue; + $this->geoBox['n']=$geo->getElementsByTagName('northBL')->item(0)->nodeValue; + } + //提取ESRI格式中的UUID + if (empty($this->uuid)) + { + @$this->uuid=$this->dom->getElementsByTagName('MetaID')->item(0)->nodeValue; + //剔除前后大括号 + $this->uuid=trim($this->uuid,'{'); + $this->uuid=trim($this->uuid,'}'); + } + //根据mdFileID来判断uuid + //如果mdFileID为uuid的组织形式,则进行提取 + if (strlen(trim($this->mdFileID))==36 && empty($this->uuid)) + $this->uuid=trim($this->mdFileID); + //仍然没有UUID信息,则创建一个 + if (empty($this->uuid)) + { + $this->uuid=new uuid(); + $this->uuid=$this->uuid->toString(); + //反馈回XML文件 + $mdfile=$this->dom->getElementsByTagName('mdFileID'); + if ($mdfile->length>0) { + $this->dom->getElementsByTagName('mdFileID')->item(0)->nodeValue=$this->uuid; + } else { + $mdfile=$this->dom->createElement('mdFileID', $this->uuid); + $this->dom->getElementsByTagName('Metadata')->item(0)->appendChild($mdfile); + } + } + //提取时间信息 + $tm_period=$this->dom->getElementsByTagName('TM_Period'); + foreach($tm_period as $period) + { + $this->timebegin=$period->getElementsByTagName('begin')->item(0)->nodeValue; + $this->timeend=$period->getElementsByTagName('end')->item(0)->nodeValue; + } + $tm_day=$this->dom->getElementsByTagName('TM_CalDate'); + foreach($tm_day as $day) + { + $this->timebegin=$day->getElementsByTagName('calDate')->item(0)->nodeValue; + } + //Todo:处理缩略图,限制为一个。 + //$thumb=$this->dom->getElementsByTagName('Thumbnail'); + $xpath = new DOMXPath($this->dom); + $query = '//metadata/Binary/Thumbnail/Data';//should be Metadata + $entries = $xpath->query($query); + if ($entries->length>0) + $this->thumbnail=$entries->item(0)->nodeValue; + else { + $query='//Metadata/Binary/Thumbnail/Data'; + $entries=$xpath->query($query); + @$this->thumbnail=$entries->item(0)->nodeValue; + } + //如果是从GEONETWORK获取,判断是否已有缩略图,获取最小的缩略图 + $graphs=$this->dom->getElementsByTagName('graphOver'); + foreach ($graphs as $g) + { + if ($g->getElementsByTagName('bgFileDesc')->item(0)->nodeValue=='thumbnail') { + $this->graph['filename']=$g->getElementsByTagName('bgFileName')->item(0)->nodeValue; + $this->graph['filedesc']='thumbnail'; + $this->graph['filetype']=$g->getElementsByTagName('bgFileType')->item(0)->nodeValue; + } + } + } +} +?> \ No newline at end of file diff --git a/README.md b/README.md index f45ccfe..2e726f8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # 元数据版本批量更新工具 -在批量对元数据进行更新后,还需要对其版本进行更新才能反映到数据中心的前台。 +在批量对元数据进行更新后,还需要对其版本进行更新才能反映到数据中心的前台。批量更新不发送邮件。 * 按照专题进行更新 -* 按照UUID进行更新 +* 按照UUID进行更新(多行文本) * 指定changelog +* 根据指定的更新条件对元数据直接更新并进行版本更新提交 + +先实现命令行版本,以后集成到系统后台。 \ No newline at end of file diff --git a/config.php b/config.php new file mode 100644 index 0000000..6f89292 --- /dev/null +++ b/config.php @@ -0,0 +1,11 @@ +db=$config->db; + $this->versionTable=$config->versionTable; + $this->changelog=$config->changelog; + $this->db = pg_connect("dbname=metadata user=gis password=gispassword host=210.77.68.241"); + $this->err=array(); + $this->userid=$config->userid; + } + + function __destruct() + { + pg_close($link); + } + + //版本更新:指定versionid + function update($uuid,$versionid,$changelog) + { + // 1. 保存变化记录 save changelog & userid + $sql = "UPDATE {$this->versionTable} SET changelog='$changelog',userid=$this->userid WHERE id=$versionid and uuid='$uuid'"; + pg_query($this->db,$sql); + + // 2. 同步元数据 + $sql = "select xml from {$this->versionTable} where id=$versionid and uuid='$uuid'"; + $result=pg_query($this->db,$sql); + $row = pg_fetch_row($result); + $iso=new ISO19115(); + @$iso->loadXML($row[0]); + if ($iso->validate()) + { + $this->err[]="元数据: ".$uuid." 导入过程中发现错误。
".implode("
",$iso->error); + } + @$iso->saveDB($this->db); + + // 3. 移除中间版本 + $sql="delete from {$this->versionTable} where uuid='$uuid' and changelog is null"; + pg_query($this->db,$sql); + pg_free_result($result); + } + + //版本更新:以最新的一个版本进行更新 + function update($uuid,$changelog) + { + // 1. 保存变化记录 save changelog & userid + $sql = "UPDATE {$this->versionTable} SET changelog='$changelog',userid=$this->userid WHERE id in (select id from {$this->versionTable} where uuid='$uuid' order by ts_created desc limit 1)"; + pg_query($this->db,$sql); + + // 2. 同步元数据 + $sql = "select xml from {$this->versionTable} where uuid='$uuid' order by ts_created desc limit 1"; + $result=pg_query($this->db,$sql); + $row = pg_fetch_row($result); + $iso=new ISO19115(); + @$iso->loadXML($row[0]); + if ($iso->validate()) + { + $this->err[]="元数据: ".$uuid." 导入过程中发现错误。
".implode("
",$iso->error); + } + @$iso->saveDB($this->db); + + // 3. 移除中间版本 + $sql="delete from {$this->versionTable} where uuid='$uuid' and changelog is null"; + pg_query($this->db,$sql); + pg_free_result($result); + } + + //专题更新:将指定专题的数据,全部按照最新版本进行更新 + function update_by_source($sourceid,$changelog) + { + // 1. 保存变化记录 save changelog & userid + $sql = "UPDATE {$this->versionTable} SET changelog='$changelog',userid=$this->userid WHERE id in ( + select distinct on (uuid) id from {$this->versionTable} where uuid in (select uuid from datasource where sourceid=$sourceid) order by uuid,ts_created desc + )"; + pg_query($this->db,$sql); + + // 2. 同步元数据 + $sql = "select xml from {$this->versionTable} WHERE id in ( + select distinct on (uuid) id from {$this->versionTable} where uuid in (select uuid from datasource where sourceid=$sourceid) order by uuid,ts_created desc + )"; + $result=pg_query($this->db,$sql); + while ($row = pg_fetch_row($result)) + { + $iso=new ISO19115(); + @$iso->loadXML($row[0]); + if ($iso->validate()) + { + $this->err[]="元数据: ".$uuid." 导入过程中发现错误。
".implode("
",$iso->error); + } + @$iso->saveDB($this->db); + } + // 3. 移除中间版本 + $sql="delete from {$this->versionTable} where uuid in (select distinct uuid from datasource where sourceid=$sourceid) and changelog is null"; + pg_query($this->db,$sql); + pg_free_result($result); + } + + //版本删除 + function delete($uuid,$versionid) + { + $sql = "DELETE FROM {$this->versionTable} WHERE uuid='$uuid' and id=$versionid"; + return pg_query($this->db, $sql); + } + + //todo: 版本直接发布(仅发布之前为评审状态的数据) + function release($uuid,$versionid) + { + //todo + $sql = "SELECT s.*,v.xml,m.title FROM en.mdstatus s left join en.mdversion v on s.uuid=v.uuid + left join en.metadata m on s.uuid=m.uuid WHERE v.id=?"; + return pg_query($this->db,$sql); + } + function release($uuid) + { + //todo + } + function release_by_source($sourceid) + { + //todo + } + } \ No newline at end of file