1

我正在尝试解析从 WFS 请求到 GeoServer 的 XML(或 GML)回复。

我的目标是将 XML 提取到一个漂亮的整洁数组中,然后我可以显示、导出等。

我的 XML 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection numberOfFeatures="52" timeStamp="2012-06-28T10:11:02.193Z" xsi:schemaLocation="http://squirrel.bis.local/bis_workspace http://squirrel.bis.local:8080/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=bis_workspace%3Abis_1_priority_species http://www.opengis.net/wfs http://squirrel.bis.local:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd" xmlns:opengeo="http://opengeo.org" xmlns:ogc="http://www.opengis.net/ogc" xmlns:bis_workspace="http://squirrel.bis.local/bis_workspace" xmlns:world="http://world.opengeo.org" xmlns:wfs="http://www.opengis.net/wfs" xmlns:medford="http://medford.opengeo.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:usa="http://usa.opengeo.org" xmlns:xlink="http://www.w3.org/1999/xlink">
<gml:featureMembers>
<bis_workspace:bis_1_priority_species gml:id="bis_1_priority_species.fid--2f086452_138094a10a0_116d">

<bis_workspace:id>27407951</bis_workspace:id>
<bis_workspace:gridref>SN123456</bis_workspace:gridref>
<bis_workspace:species>Milvus milvus</bis_workspace:species>
<bis_workspace:common>Red Kite</bis_workspace:common>
<bis_workspace:date>2004</bis_workspace:date>
<bis_workspace:comments>
</bis_workspace:comments>
<bis_workspace:family>Accipitridae</bis_workspace:family>
</bis_workspace:bis_1_priority_species>

<bis_workspace:bis_1_priority_species gml:id="bis_1_priority_species.fid--2f086452_138094a10a0_116e">
<bis_workspace:id>28064165</bis_workspace:id>
<bis_workspace:gridref>SN123456</bis_workspace:gridref>
<bis_workspace:species>Lutra lutra</bis_workspace:species>
<bis_workspace:common>European Otter</bis_workspace:common>
<bis_workspace:date>09/11/2001</bis_workspace:date>
<bis_workspace:comments>spraint</bis_workspace:comments>
<bis_workspace:family>Mustelidae</bis_workspace:family>
</bis_workspace:bis_1_priority_species>

</gml:featureMembers>
</wfs:FeatureCollection>

我希望最终结果如下所示:

Array
(
    [0] => Array
    (
            [id] => 27407951
            [gridref] => SN123456
            [species] => Milvus milvus
            [common] => Red Kite
            [date] => 2004
            [comments] => 
            [family] => Accipitridae
        )

[1] => Array
    (
        [id] => 28064165
        [gridref] => SN123456
        [species] => Lutra lutra
        [common] => European Otter
        [date] => 09/11/2001
        [comments] => spraint
        [family] => Mustelidae
    )

[2] => Array
    (
        [id] => 27516850
        [gridref] => SN123456
        [species] => Tyto alba
        [common] => Barn Owl
        [date] => 2004
        [comments] => Pair, nest box in tree, 2 chicks
        [family] => Tytonidae
    )

)

等等等等

我正在使用以下代码 - 确实有效 - 但它似乎效率低下。对于 XML 中的每条记录,代码都必须解析整个 XML 回复。如果只有 20-30 条记录,这很好,但这个 XML 回复可能包含数千条记录。

有没有一种方法可以只扫描 XML 文件 1 次来构建这个数组?

这是PHP:

    //Parse the XML
    $xml = simplexml_load_string($wfs_reply, NULL, NULL, "http://squirrel.bis.local/bis_workspace");
    $xml->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs');
    $xml->registerXPathNamespace('gml', 'http://www.opengis.net/gml');
    $xml->registerXPathNamespace('bis_workspace', 'http://squirrel.bis.local/bis_workspace');

    $count = 0;
    $feature_members_array = array();
    $feature_members_layer_path = "//bis_workspace:" . $layer_name; //I.e. '//bis_workspace:bis_1_priority_species'
    foreach($xml->xpath($feature_members_layer_path) as $feature_members_raw)
    {

        $feature_member_id = $feature_members_raw->xpath('//bis_workspace:id');
            $feature_members_array[$count]['id'] = (string)$feature_member_id[$count];
        $feature_member_gridref = $feature_members_raw->xpath('//bis_workspace:gridref');
            $feature_members_array[$count]['gridref'] = (string)$feature_member_gridref[$count];
        $feature_member_species = $feature_members_raw->xpath('//bis_workspace:species');
            $feature_members_array[$count]['species'] = (string)$feature_member_species[$count];
        $feature_member_common = $feature_members_raw->xpath('//bis_workspace:common');
            $feature_members_array[$count]['common'] = (string)$feature_member_common[$count];
        $feature_member_date = $feature_members_raw->xpath('//bis_workspace:date');
            $feature_members_array[$count]['date'] = (string)$feature_member_date[$count];
        $feature_member_comments = $feature_members_raw->xpath('//bis_workspace:comments');
            $feature_members_array[$count]['comments'] = (string)$feature_member_comments[$count];
        $feature_member_family = $feature_members_raw->xpath('//bis_workspace:family');
            $feature_members_array[$count]['family'] = (string)$feature_member_family[$count];

        $count ++;
    }

非常感谢,史蒂夫

4

3 回答 3

1

我也一直在努力处理 WFS XML 中的名称空间。我的解决方案是切换到 JSON!

如果您的 WFS 支持,您可以添加outputFormat=json到 WFS 请求中,事情会变得更容易:)

于 2013-04-11T00:05:40.733 回答
0

另一个解决方案(可能对某人有帮助):

gml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<gml:FeatureCollection xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.safe.com/gml/fme">
   <ezs:version>2</ezs:version>
   <ezs:reference class="16" key="BA2011_00001_1111"/>
   <gml:featureMember>
      <gml:surfaceProperty>
         <gml:Surface srsName="urn:adv:crs:ETRS89_UTM32">
            <gml:patches>
               <gml:PolygonPatch>
                  <ezs:attr>4220</ezs:attr>
                  <gml:exterior>
                     <gml:Ring>
                        <gml:curveMember>
                           <gml:Curve>
                              <ezs:prio>200</ezs:prio>
                              <ezs:attr>8001</ezs:attr>
                              <gml:segments>
                                 <gml:LineStringSegment>
                                    <gml:posList dimension="2">412575.990 5791993.100 412595.334 5791979.677 412590.991 5791956.384 412574.411 5791969.017 412575.990 5791993.100</gml:posList>
                                 </gml:LineStringSegment>
                              </gml:segments>
                           </gml:Curve>
                        </gml:curveMember>
                     </gml:Ring>
                  </gml:exterior>
               </gml:PolygonPatch>
            </gml:patches>
         </gml:Surface>
      </gml:surfaceProperty>
   </gml:featureMember>
</gml:FeatureCollection>

编码:

$xmlFile = 'daten2.gml';
//Parse the XML
$xml = @simplexml_load_file($xmlFile);
$xpath = $xml->xpath( '//gml:PolygonPatch' );

$ezs_attr = (string) $xpath[0]->attr;

echo "The value0: $ezs_attr"; 
$xpath2 = $xml->xpath( '//gml:Curve' );
$xpath3 = $xml->xpath( '//gml:posList' );
$xpath4 = $xml->xpath( '//gml:FeatureCollection' );
$curve_ezs_prio = (string) $xpath2[0]->prio;
$curve_ezs_attr = (string) $xpath2[0]->attr;
echo "<br>";
echo "The value1: $curve_ezs_prio"; 
echo "<br>";
echo "The value2: $curve_ezs_attr"; 
echo "<br>";
echo "The value3: ".$xpath3[0]; 
echo "<br>";
echo "The value4: ".$xpath4[0]; 
echo "<br>";
echo "The value5: ".$xpath4[0]->reference->attributes()->key;

输出:

The value0: 4220
The value1: 200
The value2: 8001
The value3: 412575.990 5791993.100 412595.334 5791979.677 412590.991 5791956.384 412574.411 5791969.017 412575.990 5791993.100
The value4:
The value5: BA2011_00001_1111
于 2019-11-26T17:16:54.603 回答
0

我也需要弄清楚这一点,而我的来源没有 JSON 响应。诀窍在于使用$xml->getNamespaces(true)并使用它作为检索孩子的参数。

这有效:

$xml = '<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection numberOfFeatures="52" timeStamp="2012-06-28T10:11:02.193Z" xsi:schemaLocation="http://squirrel.bis.local/bis_workspace http://squirrel.bis.local:8080/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=bis_workspace%3Abis_1_priority_species http://www.opengis.net/wfs http://squirrel.bis.local:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd" xmlns:opengeo="http://opengeo.org" xmlns:ogc="http://www.opengis.net/ogc" xmlns:bis_workspace="http://squirrel.bis.local/bis_workspace" xmlns:world="http://world.opengeo.org" xmlns:wfs="http://www.opengis.net/wfs" xmlns:medford="http://medford.opengeo.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:usa="http://usa.opengeo.org" xmlns:xlink="http://www.w3.org/1999/xlink">
    <gml:featureMembers>
        <bis_workspace:bis_1_priority_species gml:id="bis_1_priority_species.fid--2f086452_138094a10a0_116d">

            <bis_workspace:id>27407951</bis_workspace:id>
            <bis_workspace:gridref>SN123456</bis_workspace:gridref>
            <bis_workspace:species>Milvus milvus</bis_workspace:species>
            <bis_workspace:common>Red Kite</bis_workspace:common>
            <bis_workspace:date>2004</bis_workspace:date>
            <bis_workspace:comments>
            </bis_workspace:comments>
            <bis_workspace:family>Accipitridae</bis_workspace:family>
        </bis_workspace:bis_1_priority_species>

        <bis_workspace:bis_1_priority_species gml:id="bis_1_priority_species.fid--2f086452_138094a10a0_116e">
            <bis_workspace:id>28064165</bis_workspace:id>
            <bis_workspace:gridref>SN123456</bis_workspace:gridref>
            <bis_workspace:species>Lutra lutra</bis_workspace:species>
            <bis_workspace:common>European Otter</bis_workspace:common>
            <bis_workspace:date>09/11/2001</bis_workspace:date>
            <bis_workspace:comments>spraint</bis_workspace:comments>
            <bis_workspace:family>Mustelidae</bis_workspace:family>
        </bis_workspace:bis_1_priority_species>

    </gml:featureMembers>
</wfs:FeatureCollection>';

$xml = simplexml_load_string($xml);
$ns = $xml->getNamespaces(true);
$species_list = array();
foreach ($xml->children($ns['gml'])->featureMembers->children($ns['bis_workspace'])->bis_1_priority_species as $species_data) {
    $species = array();
    foreach ($species_data as $key => $value) {
        $species[$key] = (string) $value;
    }
    $species_list[] = $species;
}
echo "<pre>";
var_export($species_list);
echo "</pre>";

于 2019-07-24T20:28:41.483 回答