PHP使用simplexml_load_file解析带GML标签XML报错如何解决
解决方法
问题原因
SimpleXML不支持直接通过{'gml:xxx'}的对象属性形式访问带命名空间的节点,gml是XML自定义命名空间前缀,必须显式指定命名空间后才能读取对应节点。
解决方案1:使用children()方法指定命名空间
这是最简便的方法,不需要提前硬编码命名空间地址,直接从当前XML文件中提取命名空间即可:
<?php if (file_exists('doc.xml')) { $xml = simplexml_load_file('doc.xml'); } // 提取XML中所有注册的命名空间 $namespaces = $xml->getNamespaces(true); // 拿到gml前缀对应的命名空间URI $gmlNamespace = $namespaces['gml']; // 访问gml命名空间下的节点时,先调用children()传入命名空间,之后直接写节点名即可,不需要加gml前缀 foreach ($xml->par->children($gmlNamespace)->Polygon->outerBoundaryIs->LinearRing->coordinates as $coords) { // 强制转字符串避免返回SimpleXMLElement对象 echo (string)$coords; echo '<br>'; }
解决方案2:使用XPath查询
如果需要更灵活的节点定位,可以用XPath,提前注册gml命名空间即可:
<?php if (file_exists('doc.xml')) { $xml = simplexml_load_file('doc.xml'); } // 注册gml命名空间,URI和XML根节点中xmlns:gml属性的值保持一致即可 $xml->registerXPathNamespace('gml', 'http://www.opengis.net/gml'); // 直接查询所有符合路径的coordinates节点 $coordsList = $xml->xpath('//par/gml:Polygon/gml:outerBoundaryIs/gml:LinearRing/gml:coordinates'); foreach ($coordsList as $coords) { echo (string)$coords; echo '<br>'; }
注意事项
- 如果你不确定XML中gml对应的命名空间地址,优先用第一种方案的
getNamespaces(true)动态获取,避免硬编码地址不匹配导致读取失败 - 读取节点内容时建议强制转
(string)类型,避免后续操作把SimpleXMLElement对象当成字符串处理报错
内容的提问来源于stack exchange,提问作者AdBess
相关产品推荐
相关产品推荐

