You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中SimpleXML无法加载GML数据,如何解析为数组?

解析带命名空间的GML XML数据(PHP SimpleXML)

问题场景

有如下GML格式的XML数据:

<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://ogr.maptools.org/ fire_districts.xsd"
     xmlns:ogr="http://ogr.maptools.org/"
     xmlns:gml="http://www.opengis.net/gml">
  <gml:boundedBy>
    <gml:Box>
      <gml:coord><gml:X>112.921100000165</gml:X><gml:Y>-43.65832660868602</gml:Y></gml:coord>
      <gml:coord><gml:X>153.6407999999201</gml:X><gml:Y>-10.05939999961026</gml:Y></gml:coord>
    </gml:Box>
  </gml:boundedBy>

  <gml:featureMember>
    <ogr:IDM00007 fid="IDM00007.0">
      <ogr:geometryProperty><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>153.551804332204,-28.1645084912738 153.586699999805,-28.2582999997451 153.573299999695,-28.3133 153.582500000375</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
      <ogr:AAC>NSW_FW001</ogr:AAC>
      <ogr:DIST_NO>1</ogr:DIST_NO>
      <ogr:DIST_NAME>Far North Coast</ogr:DIST_NAME>
      <ogr:STATE_CODE>NSW</ogr:STATE_CODE>
      <ogr:SOURCE>RFS</ogr:SOURCE>
      <ogr:GROUP_NAME xsi:nil="true"/>
    </ogr:IDM00007>
  </gml:featureMember>
  <gml:featureMember>
    <ogr:IDM00007 fid="IDM00007.1">
      <ogr:geometryProperty><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>153.261225211474,-29.9401032948311 153.19820000033,-30.038899999935 153.20060000039,-30.1036999997551 153.214099999715</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
      <ogr:AAC>NSW_FW002</ogr:AAC>
      <ogr:DIST_NO>2</ogr:DIST_NO>
      <ogr:DIST_NAME>North Coast</ogr:DIST_NAME>
      <ogr:STATE_CODE>NSW</ogr:STATE_CODE>
      <ogr:SOURCE>RFS</ogr:SOURCE>
      <ogr:GROUP_NAME xsi:nil="true"/>
    </ogr:IDM00007>
  </gml:featureMember>
</ogr:FeatureCollection>

尝试用PHP SimpleXML解析,代码如下:

<?php
$data = file_get_contents("fire_districts.gml");
$xml = new SimpleXMLElement($data);
$xml->registerXPathNamespace('f', 'http://ogr.maptools.org/');
$xml->registerXPathNamespace('g', 'http://www.opengis.net/gml');
$gml = $xml->xpath('/f:FeatureCollection/g:featureMember');
print_r($gml);
?>

输出结果仅显示空的SimpleXMLElement对象数组:

Array
(
    [0] => SimpleXMLElement Object
        (
        )

    [1] => SimpleXMLElement Object
        (
        )
)

需要修改代码以成功将GML数据加载为数组。

解决方案

核心原因

SimpleXML在处理带命名空间的XML时,直接用print_r/var_dump不会展示命名空间内的子元素,但元素实际是存在的。需要通过指定命名空间来访问子节点,或者将其转换为普通数组。

修正代码示例

以下是完整的解析代码,可将GML数据提取为结构化数组:

<?php
$data = file_get_contents("fire_districts.gml");
$xml = new SimpleXMLElement($data);

// 注册命名空间
$xml->registerXPathNamespace('ogr', 'http://ogr.maptools.org/');
$xml->registerXPathNamespace('gml', 'http://www.opengis.net/gml');

// 定位所有featureMember节点
$featureMembers = $xml->xpath('/ogr:FeatureCollection/gml:featureMember');

$result = [];
foreach ($featureMembers as $member) {
    // 获取ogr命名空间下的IDM00007节点
    $district = $member->children('ogr', true)->IDM00007;
    
    $item = [
        'fid' => (string)$district['fid'],
        'AAC' => (string)$district->AAC,
        'DIST_NO' => (int)$district->DIST_NO,
        'DIST_NAME' => (string)$district->DIST_NAME,
        'STATE_CODE' => (string)$district->STATE_CODE,
        'SOURCE' => (string)$district->SOURCE,
        'GROUP_NAME' => isset($district->GROUP_NAME) ? (string)$district->GROUP_NAME : null,
        // 提取坐标数据
        'coordinates' => (string)$district->geometryProperty->children('gml', true)->Polygon->outerBoundaryIs->LinearRing->coordinates
    ];
    
    $result[] = $item;
}

print_r($result);
?>

关键说明

  • 命名空间访问:使用children('命名空间前缀', true)来访问对应命名空间下的子元素,第二个参数true表示直接使用前缀而非完整URI。
  • 强制类型转换:SimpleXMLElement对象需要转换为字符串/整数等基础类型,否则会保留对象结构。
  • 属性提取:通过$element['属性名']的方式获取节点属性,同样需要强制转换为字符串。

输出示例

Array
(
    [0] => Array
        (
            [fid] => IDM00007.0
            [AAC] => NSW_FW001
            [DIST_NO] => 1
            [DIST_NAME] => Far North Coast
            [STATE_CODE] => NSW
            [SOURCE] => RFS
            [GROUP_NAME] => 
            [coordinates] => 153.551804332204,-28.1645084912738 153.586699999805,-28.2582999997451 153.573299999695,-28.3133 153.582500000375
        )

    [1] => Array
        (
            [fid] => IDM00007.1
            [AAC] => NSW_FW002
            [DIST_NO] => 2
            [DIST_NAME] => North Coast
            [STATE_CODE] => NSW
            [SOURCE] => RFS
            [GROUP_NAME] => 
            [coordinates] => 153.261225211474,-29.9401032948311 153.19820000033,-30.038899999935 153.20060000039,-30.1036999997551 153.214099999715
        )

)

内容的提问来源于stack exchange,提问作者Mike Manning

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:24:33