2016-12-14 103 views
1

XML:查询多名称空间的XML

<lev:Locatie axisLabels="x y" srsDimension="2" srsName="epsg:28992" uomLabels="m m"> 
    <gml:exterior xmlns:gml="http://www.opengis.net/gml"> 
     <gml:LinearRing> 
      <gml:posList> 
      222518.0 585787.0 222837.0 585875.0 223229.0 585969.0 223949.0 586123.0 223389.0 586579.0 223305.0 586564.0 222690.0 586464.0 222706.0 586319.0 222424.0 586272.0 222287.0 586313.0 222054.0 586517.0 221988.0 586446.0 222174.0 586305.0 222164.0 586292.0 222172.0 586202.0 222232.0 586143.0 222279.0 586149.0 222358.0 586076.0 222422.0 586018.0 222518.0 585787.0 
      </gml:posList> 
     </gml:LinearRing> 
    </gml:exterior> 
</lev:Locatie> 

我需要去的GML:posList。我尝试以下

的SimpleXML:

$xmldata  = new SimpleXMLElement($xmlstr); 
$xmlns  = $xmldata->getNamespaces(true); 

$retval = array(); 

foreach($xmldata as $attr => $child) { 
    if ((string)$child !== '') { 
     $retval[$attr] = (string)$child; 
    } 
    else { 
     $retval[$attr] = $child->children($xmlns['gml']); 
    } 
} 
var_export($retval); 

的XPath:

$domdoc = new DOMDocument(); 
$domdoc->loadXML($xml); 
$xpath = new DOMXpath($domdoc); 
$xpath->registerNamespace('l', $xmlns['lev']); 
$xpath->registerNamespace('g', $xmlns['gml']); 
var_export($xml->xpath('//g:posList')); 

如果我查询列弗属性:地区,我可以让他们,但是,我似乎无法检索GML :posList的值或例如gml:exterior的属性。我知道我做错了什么,我只是没有看到什么...

回答

1

您正在DOMXpath实例上注册名称空间,但使用SimpleXMLElement::xpath()调用。这是行不通的。您可以使用SimpleXMLElement::registerXpathNamespace()SimpleXMLElement上注册它们,或者切换到DOM并使用DOMXpath::evaluate()。这些属性没有前缀,因此它们不在名称空间中。 gml:exterior没有任何属性,只有名称空间的定义。它看起来像一个属性,但解析器对它的处理方式不同。

关于DOMXpath::evaluate()的好处是,它可以是一个节点列表或一个标量,具体取决于Xpath表达式。所以你可以直接获取一个值。

例如,gml:posList

$xmlString = <<<'XML' 
<lev:Locatie axisLabels="x y" srsDimension="2" srsName="epsg:28992" uomLabels="m m" xmlns:lev="urn:lev"> 
    <gml:exterior xmlns:gml="http://www.opengis.net/gml"> 
     <gml:LinearRing> 
      <gml:posList> 
      222518.0 585787.0 222837.0 
      </gml:posList> 
     </gml:LinearRing> 
    </gml:exterior> 
</lev:Locatie> 
XML; 

$document = new DOMDocument(); 
$document->loadXML($xmlString); 
$xpath = new DOMXpath($document); 
$xpath->registerNamespace('g', 'http://www.opengis.net/gml'); 
var_export( 
    $xpath->evaluate('normalize-space(//g:posList)') 
); 

输出:

'222518.0 585787.0 222837.0' 

normalize-space()是XPath函数替换空格的所有序列与单个的空间和修剪的结果。因为它是一个字符串函数,它会触发位置路径中的第一个节点的隐式转换。

+0

谢谢托马斯,我会试试看 –