/** * @internal extract registered XMLNS namespaces using XPath * */ private function extractNamespaces() { $namespaces = $this->DOMXPath->query('namespace::*'); foreach ($namespaces as $namespace) { if ($namespace->localName !== 'xml') { $this->DOMNamespaces[$namespace->localName] = $this->DOMDocument->lookupNamespaceURI($namespace->localName); } } }
protected function createFeatureTypeFromXml($xml, $myWfs, $featureTypeName) { $newFeatureType = new WfsFeatureType($myWfs); $doc = new DOMDocument(); $doc->loadXML($xml); $xpath = new DOMXpath($doc); $xpath->registerNamespace("xs", "http://www.w3.org/2001/XMLSchema"); // populate a Namespaces Hastable where we can use thec namesopace as a lookup for the prefix // and also keep a $namespaces = array(); $namespaceList = $xpath->query("//namespace::*"); $targetNamespace = $doc->documentElement->getAttribute("targetNamespace"); $targetNamespaceNode = null; foreach ($namespaceList as $namespaceNode) { $namespaces[$namespaceNode->nodeValue] = $namespaceNode->localName; if ($namespaceNode->nodeValue == $targetNamespace) { $targetNamespaceNode = $namespaceNode; } $newFeatureType->addNamespace($namespaceNode->localName, $namespaceNode->nodeValue); } list($ftLocalname, $ftTypePrefix) = array_reverse(explode(":", $featureTypeName)); // for the sake of simplicity we only care about top level elements. Seems to have worked so far $query = sprintf("/xs:schema/xs:element[@name='%s']", $ftLocalname); $elementList = $xpath->query($query); foreach ($elementList as $elementNode) { $elementName = $elementNode->getAttribute("name"); $elementType = $elementNode->getAttribute("type"); // if Type is empty, we assume an anonymousType, else we go looking for the anmed Type if ($elementType == "") { // Just querying for complexTypes containing a Sequence - good enough for Simple Features $query = "xs:complexType//xs:element"; $subElementList = $xpath->query($query, $elementNode); } else { // The elementType is now bound to a prefix e.g. topp:housType // if the prefix is in the targetNamespace, changces are good it's defined in this very document // if the prefiox is not in the targetNamespace, it's likely not defined here, and we bail list($elementTypeLocalname, $elementTypePrefix) = array_reverse(explode(":", $elementType)); $elementTypeNamespace = $doc->lookupNamespaceURI($elementTypePrefix); if ($elementTypeNamespace !== $targetNamespaceNode->nodeValue) { $e = new mb_warning("Tried to parse FeatureTypeName {$featureTypeName} : {$elementType} is not in the targetNamespace"); break; } // Just querying for complexTypes containing a Sequence - good enough for Simple Features $query = sprintf("//xs:complexType[@name='%s']//xs:element", $elementTypeLocalname); $subElementList = $xpath->query($query); } foreach ($subElementList as $subElement) { // Since this is a rewrite of the old way, it reproduces it quirks // in this case the namespace of the type was cut off for some reason $name = $subElement->getAttribute('name'); $typeParts = explode(":", $subElement->getAttribute('type')); if (count($typeParts) == 1) { $type = $typeParts[0]; } else { $type = $typeParts[1]; } $newFeatureType->addElement($name, $type); } } return $newFeatureType; }
<?php $doc = new DOMDocument(); $doc->load(dirname(__FILE__) . "/nsdoc.xml"); $root = $doc->documentElement; $duri = $doc->lookupNamespaceURI("ns2") . "\n"; $euri = $root->lookupNamespaceURI("ns2") . "\n"; var_dump($duri == $euri); $dpref = $doc->lookupPrefix("http://ns2") . "\n"; $epref = $root->lookupPrefix("http://ns2") . "\n"; var_dump($dpref == $epref); $disdef = $doc->isDefaultNamespace("http://ns") . "\n"; $eisdef = $root->isDefaultNamespace("http://ns") . "\n"; var_dump($dpref === $epref);