我正在尝试解析从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&version=1.1.0&request=DescribeFeatureType&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回复可能包含数千条记录。
有没有办法只用1次扫描XML文件来构建这个数组?
这是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 ++;
}
非常感谢, 史蒂夫
答案 0 :(得分:0)
我也一直在努力处理WFS XML中的命名空间。我的解决方案是切换到JSON!
如果您的WFS支持,您可以将outputFormat=json
添加到WFS请求中,事情变得更加容易:)
答案 1 :(得分: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&version=1.1.0&request=DescribeFeatureType&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>";
答案 2 :(得分:0)
另一种解决方案(可能对某人有用)
gml文件:
platform=[]
for row_c, row in enumerate(level):
for counter, item in enumerate(row):
if item == 'P':
rb=Red_Block()
rb.rect.topleft = (counter*31, row_c*31)
platform.append(rb)
player1.set_platform(platform)
running = True
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
if event.key == K_DOWN:
player1.move_down()
if event.key == K_LEFT:
player1.move_left()
if event.key == K_RIGHT:
player1.move_right()
if event.key == K_UP:
player1.move_up()
elif event.type == QUIT:
running = False
screen.fill((0, 0, 0))
for rb in platform:
screen.blit(rb.surf, rb.rect.topleft)
player1.gravity()
screen.blit(player1.surf, player1.rect.topleft)
pygame.display.flip()
代码:
<?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;