带有名称空间的PHP xpath查询返回破碎的节点



我尝试用PHP 8.1解析wfs xml结构,并有以下代码片段:

<?php
$rawContent = file_get_contents('https://www.geobasisdaten.niedersachsen.de/doorman/noauth/WFS_NI_2211_ATKIS_BDLM-Modell-konform?request=getCapabilities&service=wfs&version=1.1.0');
// source: https://numis.niedersachsen.de/trefferanzeige?docuuid=e26aebd6-cc4c-4af2-8be3-8719b808df5d&plugid=/ingrid-group:iplug-csw-dsc-lgln&docid=julvu30Bh4CjFjsS0QgC
// the following works fine:
// $rawContent = file_get_contents('https://pegelonline.wsv.de/webservices/gis/aktuell/wfs?request=GetCapabilities&service=WFS&typename=gk%3Awaterlevels&version=1.1.0');
// source: https://pegelonline.wsv.de
$wfsStructure= new SimpleXMLElement($rawContent);
$wfsStructure->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs');
$wfsStructure->registerXPathNamespace('ows', 'http://www.opengis.net/ows/1.1');
$wfsStructure->registerXPathNamespace('ogc', 'http://www.opengis.net/ogc');
$resultList = $wfsStructure->xpath('//*[local-name()='FeatureType']');
// same result with following xpath
// $resultList = $wfsStructure->xpath('/wfs:WFS_Capabilities/wfs:FeatureTypeList//wfs:FeatureType');
var_dump($resultList);

结果有点无聊:

array(105) {
[0]=>
object(SimpleXMLElement)#2 (0) {
}
[1]=>
object(SimpleXMLElement)#3 (0) {
}
[2]=>
object(SimpleXMLElement)#4 (0) {
}
(…)
[103]=>
object(SimpleXMLElement)#105 (0) {
}
[104]=>
object(SimpleXMLElement)#106 (0) {
}
}

所以我的脚本检测到104个节点,但它们都是空的。你知道我为什么会惹上麻烦吗?当我调用上面脚本中注释的其他wfs源代码时,一切正常。

您需要进行一些调整(例如,$resultList = $wfsStructure->xpath('//*[local-name()='FeatureType']');不能工作,因为您在单引号周围使用单引号而不是双引号)。

像这样试试,看看它是否有效。例如,要获取作为第二个<wfs:FeatureType>节点子节点的所有<wfs:OtherSRS>节点的文本值:

$wfsStructure= new SimpleXMLElement($rawContent);    
$wfsStructure->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs');
$resultList = $wfsStructure->xpath('//wfs:FeatureTypeList//wfs:FeatureType[2]//wfs:OtherSRS');    
foreach ($resultList as $result){
echo($result[0]."n");
}

输出应该是:

urn:ogc:def:crs:EPSG::25833
urn:ogc:def:crs:EPSG::3034
urn:ogc:def:crs:EPSG::3857
urn:ogc:def:crs:EPSG::4258
urn:ogc:def:crs:EPSG::4326
urn:ogc:def:crs:EPSG::900913

好的,我猜下一个线索:wfs文件https://www.geobasisdaten.niedersachsen.de/doorman/noauth/WFS_NI_2211_ATKIS_BDLM-Modell-konform?request=getCapabilities&service=wfs&version=1.1.0不匹配wfs模式,因为它在元素上有一些更多的wfs名称空间,不应该有wfs名称空间。

当我在将文件转换为SimpleXMLElement之前手动删除wfs名称空间时,一切都工作正常。

$rawContent = str_replace('wfs:FeatureType', 'FeatureType', $rawContent);
$rawContent = str_replace('wfs:Name', 'Name', $rawContent);
$rawContent = str_replace('wfs:Title', 'Title', $rawContent);

但我想,没有人会看到这种方法,因为我再也找不到工作了。

最新更新