'http://www.isotc211.org/2005/gts', 'srv' => 'http://www.isotc211.org/2005/srv', 'gml' => 'http://www.opengis.net/gml', 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'gco' => 'http://www.isotc211.org/2005/gco', 'gmd' => 'http://www.isotc211.org/2005/gmd', 'xlink' => 'http://www.w3.org/1999/xlink' ); private $codeListUrl = "http://www.isotc211.org/2005/resources/codeList.xml"; public function __construct ($xml = null) { if (is_null($xml)) { $this->create(); } else { $this->loadXml($xml); } } public function getUuid () { $result = $this->get("/gmd:MD_Metadata/gmd:fileIdentifier/gco:CharacterString"); if (count($result) > 0) { return $result[0]; } return null; } public function setUuid ($aUuid) { if (!Uuid::isuuid($aUuid)) { return false; } return $this->set("/gmd:MD_Metadata/gmd:fileIdentifier/gco:CharacterString", $aUuid); } public function getTitle () { $result = $this->get("/gmd:MD_Metadata/gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString"); if (count($result) == 0) { $result = $this->get("/gmd:MD_Metadata/gmd:identificationInfo/srv:SV_ServiceIdentification/gmd:citation/gmd:CI_Citation/gmd:title/gco:CharacterString"); } if (count($result) > 0) { return $result[0]; } return null; } public function getResponsibleParty () { $result = $this->get("/gmd:MD_Metadata/gmd:contact/gmd:CI_ResponsibleParty/gmd:organisationName/gco:CharacterString"); if (count($result) > 0) { return $result[0]; } return null; } public function getIndividualName () { $result = $this->get("/gmd:MD_Metadata/gmd:contact/gmd:CI_ResponsibleParty/gmd:individualName/gco:CharacterString"); if (count($result) > 0) { return $result[0]; } return null; } public function getType () { $result = $this->get("/gmd:MD_Metadata/gmd:hierarchyLevel/gmd:MD_ScopeCode"); if (count($result) > 0) { return $result[0]; } return null; } public function getKeywords () { $result = $this->get("//gmd:descriptiveKeywords/gmd:MD_Keywords/gmd:keyword/gco:CharacterString"); if (count($result) > 0) { return $result; } return null; } /** * Loads a xml file from the filesystem, * creates the dom document and loads xpath * * @return Boolean * @param $filename String */ public function loadXml($xml){ $this->doc = new DOMDocument(); $this->doc->preserveWhiteSpace = false; $this->doc->loadXML($xml); $this->loadxpath(); return true; } /** * Loads a xml file from the filesystem, * creates the dom document and loads xpath * * @return MdMetadataXml * @param $filename String */ public static function loadFile ($filename) { $xml = new MdMetadataXml(); $xml->doc = new DOMDocument(); $xml->doc->preserveWhiteSpace = false; $xml->doc->load($filename); $xml->loadxpath(); return $xml; } /** * Registers all namespaces for xpath * The namespaces should be configured * in $this->namespaces * */ private function registerNamespaces(){ foreach ($this->namespaces as $key => $val) { $this->xp->registerNamespace($key,$val); } } /** * * Creates a new dom document * */ private function create(){ $this->doc = new DOMDocument('1.0'); $this->doc->preserveWhiteSpace = false; $this->doc->encoding = "UTF-8"; $md_metadata = $this->doc->createElementNS("http://www.isotc211.org/2005/gmd",$this->rootNode); foreach ($this->namespaces as $key => $val) { $md_metadata->setAttribute('xmlns:'.$key,$val); } $this->doc->appendChild($md_metadata); $this->loadxpath(); } /** * Loads all the xpath stuff on a given dom document * */ private function loadxpath(){ $this->xp = new DOMXPath($this->doc); $this->xp->preserveWhiteSpace = false; $this->registerNamespaces(); } /** * Separates the last nodename from a xpath * * @return String * @param $path String */ private function getNodeName($path){ $nodes = explode("/",$path); return $nodes[count($nodes)-1]; } /** * Evaluates if a node exists or not * * @return Boolean * @param $parent Dom Node Object * @param $nodename String */ private function exists($parent,$nodename){ if(!is_object($parent)){ new mb_exception("class_MdMetadataXml: no parent node existent for: ".$nodename); } if($this->islist($nodename)){ if ($parent->hasChildNodes()) { $cnt = 0; foreach ($parent->childNodes as $c) { if ($c->nodeName == $this->getName($nodename)){ $cnt++; } if($this->getIndex($nodename) == $cnt){ return $c; } } } } else{ // throw new Exception("test : " .var_dump($parent)); if ($parent->hasChildNodes()) { foreach ($parent->childNodes as $c) { if ($c->nodeName == $nodename){ return $c; } } } } return false; } /** * Separates the namespace from a nodename * * @param $nodename String * @return String */ private function getNamespace($nodename){ $sep = explode(":",$nodename); return $sep[0]; } /** * Removes all brackets and indexes * from arrays in the nodename * * @param $nodename String * @return String */ private function getName($nodename){ $pattern = '/\[.*\]/'; if(preg_match($pattern,$nodename,$matches)){ $nodename = str_replace($matches[0],"",$nodename); } return $nodename; } /** * Appends a node * * @param $parent Dom Object * @param $childname String * @return Dom Node Object */ private function append($parent,$childname){ $newNode = $this->doc->createElementNS($this->namespaces[$this->getNamespace($childname)],$childname); $createdNode = $parent->appendChild($newNode); return $createdNode; } /** * Appends all nodes of an array * * @param $parent Dom Object * @param $childname String * @return Dom Node Object */ private function appendAll($parent,$childname){ $nodename = $this->getName($childname); $index = $this->getIndex($childname); $count = 0; if ($parent->hasChildNodes()) { foreach ($parent->childNodes as $c) { if ($c->nodeName == $nodename){ $count++; } } } for($i = $count; $i< $index; $i++){ $currentNode = $this->append($parent,$nodename); } return $currentNode; } /** * Checks if the node is a codelist * * @param $nodename String * @return Boolean */ private function isCodeList($nodename) { // DON'T JUST CHECK FOR 'Code's ! THERE'S A SPEC HERE: http://www.isotc211.org/2005/gmd/identification.xsd if (strstr($nodename,"MD_TopicCategoryCode")) { return false; } else if(stristr($nodename,"SV_CouplingType")) { return true; } else if(substr($nodename, -4) == "Code") { return true; } else { return false; } } /** * Inserts the value of a node * * @param $parent Dom Object * @param $value String */ private function setValue($node,$value, $type=null){ // 2010-11-29 | apour if($node->nodeName == "srv:operatesOn") { $node->setAttribute('xlink:href',$value); } else if($this->isCodeList($node->nodeName)) { $node->setAttribute('codeListValue', $value); $node->setAttribute('codeList', $this->codeListUrl."#".$this->getName($node->nodeName)); if($type){ $node->setAttribute('type',$type); // new mb_exception("set type to: " .$type); } } else { $newNode = $this->doc->createTextNode($value); if($type){ $node->setAttribute('type',$type); // new mb_exception("set type to: " .$type); } // delete all existing text nodes (allows update) $existingTextNodes = $node->childNodes; foreach ($existingTextNodes as $child) { $node->removeChild($child); } $node->appendChild($newNode); } } /** * checks if the node should be an array (without index) * * @param $nodename String * @return Boolean */ private function isarray($nodename){ $pattern = '/\[\]/'; preg_match($pattern,$nodename,$matches); if(count($matches) > 0){ return true; } else{ return false; } } /** * checks if the node should be an array with index * * @param $nodename String * @return Boolean */ private function islist($nodename){ $pattern = '/\[.+\]/'; preg_match($pattern,$nodename,$matches); if(count($matches) > 0){ return true; } else{ return false; } } /** * returns the index * * @param $nodename String * @return Integer */ private function getIndex($nodename){ $pattern = '/\[.+\]/'; preg_match($pattern,$nodename,$matches); $index = substr($matches[0], 1, -1); return intval($index); } /** * removes the empty brackets of a nodename * * @param $nodename String * @return String */ private function removeBrackets($path){ return str_replace ("[]","", $path); } /** * inserts the nodes and the value * * @param $path String * @param $value String * @return String */ public function set ($path, $value) { if (strpos($path,"/") === false) { return false; } if(empty($this->xp)){ $this->create(); } if($path == "/gmd:MD_Metadata/gmd:fileIdentifier/gco:CharacterString"){ if (!Uuid::isUuid($value)){ $value = strval(new Uuid()); } } if($path == "/gmd:MD_Metadata/gmd:dateStamp/gco:DateTime"){ $date = date("Y-m-d"); $value = $date; } $names = explode("/",$path); $currentNodes = array(); for($i=0; $irootNode){ $nodes = $this->xp->query("//*"); foreach($nodes as $node){ if($node->nodeName == $this->rootNode){ $currentNodes[$i] = $node; } } continue; } $exists = $this->exists($currentNodes[$i-1],$names[$i]); // string if(!$this->isarray($names[$i]) && !$this->islist($names[$i]) && !$exists){ $currentNodes[$i] = $this->append($currentNodes[$i-1],$names[$i]); } // array without an index else if($this->isarray($names[$i]) && !$this->islist($names[$i]) && !$exists){ $currentNodes[$i] = $this->append($currentNodes[$i-1],$this->removeBrackets($names[$i])); } //list == array with index else if($this->islist($names[$i]) && !$exists){ $currentNodes[$i] = $this->appendAll($currentNodes[$i-1],$names[$i]); } // default if exists else { $currentNodes[$i] = $exists; } // set Value if($this->getName($this->getNodeName($path)) == $currentNodes[$i]->nodeName){ $this->setValue($currentNodes[$i],$value,$type); } } return true; } /** * returns the xml document as string * * @return String */ public function __toString () { // ISO bugfix - start $array = array( 'gmd:fileIdentifier' => array(), 'gmd:language' => array(), 'gmd:characterSet' => array(), 'gmd:parentIdentifier' => array(), 'gmd:hierarchyLevel' => array(), 'gmd:hierarchyLevelName' => array(), 'gmd:contact' => array(), 'gmd:dateStamp' => array(), 'gmd:metadataStandardName' => array(), 'gmd:metadataStandardVersion' => array(), 'gmd:dataSetURI' => array(), 'gmd:locale' => array(), 'gmd:spatialRepresentationInfo' => array(), 'gmd:referenceSystemInfo' => array(), 'gmd:metadataExtensionInfo' => array(), 'gmd:identificationInfo' => array(), 'gmd:contentInfo' => array(), 'gmd:distributionInfo' => array(), 'gmd:dataQualityInfo' => array(), 'gmd:portrayalCatalogueInfo' => array(), 'gmd:metadataConstraints' => array(), 'gmd:applicationSchemaInfo' => array(), 'gmd:metadataMaintenance' => array(), 'gmd:series' => array(), 'gmd:describes' => array(), 'gmd:propertyType' => array(), 'gmd:featureType' => array(), 'gmd:featureAttribute' => array(), ); $tmpNode = $this->doc->documentElement; $xpath = new DOMXpath($this->doc); $elements = $xpath->query("*"); // Elemente merken und aus dem Dokument löschen. foreach ($elements as $element) { $array[$element->nodeName][] = $element; $tmpNode->removeChild($element); } // Elemente wieder richtig in das Dokument einbauen. foreach ($array as $key => $val) { if(!empty($val)) { foreach ($val as $element) { $tmpNode->appendChild($element); } } } // ISO bugfix - end return $this->doc->saveXML(); } /** * get the value of the node * * @param $path String * @return Array */ public function get($path){ $nodename = $this->getNodeName($path); $query = str_replace("[]","",$path); $nodes = $this->xp->query($query); $result = array(); foreach($nodes as $node){ if($node->nodeName == "srv:operatesOn") { array_push($result,$node->getAttribute('xlink:href')); } else if($this->isCodeList($nodename)){ array_push($result,$node->getAttribute('codeListValue')); } else{ array_push($result,$node->nodeValue); } } return $result; } public function getAttribute_Type($path){ $nodename = $this->getNodeName($path); $query = str_replace("[]","",$path); $nodes = $this->xp->query($query); // new mb_exception("getAttr.Type's query: ".$query); $result = array(); foreach($nodes as $node){ array_push($result,$node->getAttribute('type')); } return $result; } /** * get the length / the count of Nodes * * @param $path String * @return Integer */ public function getNodesLength($path){ $nodes = $this->xp->query($path); return $nodes->length; } public function updateIndividual($beforeUpdate,$afterUpdate){ $old = array(); $old["individualName"] = $beforeUpdate->name; $old["voice"] = $beforeUpdate->phone; $old["facsimile"] = $beforeUpdate->fax; $old["electronicMailAddress"] = $beforeUpdate->email; $old["positionName"] = $beforeUpdate->position; $new = array(); $new["individualName"] = $afterUpdate->name; $new["voice"] = $afterUpdate->phone; $new["facsimile"] = $afterUpdate->fax; $new["electronicMailAddress"] = $afterUpdate->email; $new["positionName"] = $afterUpdate->position; $query = "//gmd:CI_ResponsibleParty"; $nodes = $this->xp->query($query); foreach ($nodes as $node){ $actual = array(); $actual["individualName"] = $this->get_IndividualName($node)->nodeValue; $actual["voice"] = $this->get_Voice($node)->nodeValue; $actual["facsimile"] = $this->get_Facsimile($node)->nodeValue; $actual["electronicMailAddress"] = $this->get_ElectronicMailAddress($node)->nodeValue; $actual["positionName"] = $this->get_PositionName($node)->nodeValue; if(!array_diff($actual,$old)){ $this->get_IndividualName($node)->nodeValue = $new["individualName"]; $this->get_Voice($node)->nodeValue = $new["voice"]; $this->get_Facsimile($node)->nodeValue = $new["facsimile"]; $this->get_ElectronicMailAddress($node)->nodeValue = $new["electronicMailAddress"]; $this->get_PositionName($node)->nodeValue = $new["positionName"]; new mb_exception("update user contact to:".serialize($new)); } } } public function updateResponsibleParty($beforeUpdate,$afterUpdate){ $old = array(); $old["organisationName"] = $beforeUpdate->name; $old["deliveryPoint"] = $beforeUpdate->address; $old["postalCode"] = $beforeUpdate->postcode; $old["city"] = $beforeUpdate->city; $old["administrativeArea"] = $beforeUpdate->stateorprovince; $old["country"] = $beforeUpdate->country; $new = array(); $new["organisationName"] = $afterUpdate->name; $new["deliveryPoint"] = $afterUpdate->address; $new["postalCode"] = $afterUpdate->postcode; $new["city"] = $afterUpdate->city; $new["administrativeArea"] = $afterUpdate->stateorprovince; $new["country"] = $afterUpdate->country; $query = "//gmd:CI_ResponsibleParty"; $nodes = $this->xp->query($query); foreach ($nodes as $node){ new mb_exception("update: haveanode"); $actual = array(); $actual["organisationName"] = $this->get_OrganisationName($node)->nodeValue; $actual["deliveryPoint"] = $this->get_DeliveryPoint($node)->nodeValue; $actual["postalCode"] = $this->get_PostalCode($node)->nodeValue; $actual["city"] = $this->get_City($node)->nodeValue; $actual["administrativeArea"] = $this->get_AdministrativeArea($node)->nodeValue; $actual["country"] = $this->get_Country($node)->nodeValue; if(!array_diff($actual,$old)){ new mb_exception("update: isanode"); $this->get_OrganisationName($node)->nodeValue = $new["organisationName"]; $this->get_DeliveryPoint($node)->nodeValue = $new["deliveryPoint"]; $this->get_PostalCode($node)->nodeValue = $new["postalCode"]; $this->get_City($node)->nodeValue = $new["city"]; $this->get_AdministrativeArea($node)->nodeValue = $new["administrativeArea"]; $this->get_Country($node)->nodeValue = $new["country"]; new mb_exception("update group contact to:".serialize($new)); } } } private function xpathquery($query,$context){ $nodes = $this->xp->query($query,$context); foreach ($nodes as $node){ new mb_exception("Data:". $node->nodeValue); return $node; } } private function get_OrganisationName($context){ $query = "gmd:organisationName/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_IndividualName($context){ $query = "gmd:individualName/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_DeliveryPoint($context){ $query = "gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:deliveryPoint/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_PostalCode($context){ $query = "gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:postalCode/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_City($context){ $query = "gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:city/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_AdministrativeArea($context){ $query = "gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:administrativeArea/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_Country($context){ $query = "gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:country/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_Voice($context){ $query = "gmd:contactInfo/gmd:CI_Contact/gmd:phone/gmd:CI_Telephone/gmd:voice/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_Facsimile($context){ $query = "gmd:contactInfo/gmd:CI_Contact/gmd:phone/gmd:CI_Telephone/gmd:facsimile/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_ElectronicMailAddress($context){ $query = "gmd:contactInfo/gmd:CI_Contact/gmd:address/gmd:CI_Address/gmd:electronicMailAddress/gco:CharacterString"; return $this->xpathquery($query,$context); } private function get_PositionName($context){ $query = "gmd:positionName/gco:CharacterString"; return $this->xpathquery($query,$context); } } ?>