我正在尝试使用perl解析KML文件。我正在尝试使用XML::Simple
模块来执行此操作。
我想浏览每个地标并提取一些数据
1)Mcode
2)坐标
在阅读了几篇文章之后,我尝试了以下方法来打印所有点的坐标,但它失败了
use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
my $myFile = XMLin('ExperimentMap.kml');
foreach my $folder (@{$myFile->{Document}->{Folder}->{Placemark}}) {
print $folder->{Point}->{coordinates}."\n";
}
我使用以下KML:
<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://www.opengis.net/kml/2.2'>
<Document>
<name>ExperimentMap</name>
<description><![CDATA[]]></description>
<Folder>
<name>ExperimentLayer</name>
<Placemark>
<styleUrl>#icon-503-FF8277</styleUrl>
<name>home</name>
<ExtendedData>
<Data name='string'>
<displayName>Mcode</displayName>
<value>PLAAB</value>
</Data>
</ExtendedData>
<ExtendedData>
<Data name='string'>
<displayName>postal code</displayName>
<value>450010</value>
</Data>
</ExtendedData>
<description><![CDATA[my home
Mcode: PLAAB
postal code: 450010]]></description>
<Point>
<coordinates>80.23435592651367,13.094024942328286,0.0</coordinates>
</Point>
</Placemark>
<Placemark>
<styleUrl>#icon-503-FF8277</styleUrl>
<name>shop</name>
<ExtendedData>
<Data name='string'>
<displayName>Mcode</displayName>
<value>XMPLE</value>
</Data>
</ExtendedData>
<ExtendedData>
<Data name='string'>
<displayName>postal code</displayName>
<value>450013</value>
</Data>
</ExtendedData>
<description><![CDATA[my shop
Mcode: XMPLE
postal code: 450013]]></description>
<Point>
<coordinates>80.2437973022461,13.106230102044576,0.0</coordinates>
</Point>
</Placemark>
<Placemark>
<styleUrl>#icon-503-FF8277</styleUrl>
<name>place3</name>
<ExtendedData>
<Data name='string'>
<displayName>Mcode</displayName>
<value>UDKBL</value>
</Data>
</ExtendedData>
<ExtendedData>
<Data name='string'>
<displayName>postal code</displayName>
<value>578635</value>
</Data>
</ExtendedData>
<description><![CDATA[my school
Mcode: UDKBL
postal code: 578635]]></description>
<Point>
<coordinates>80.24688720703125,13.096198508196448,0.0</coordinates>
</Point>
</Placemark>
</Folder>
<Style id='icon-503-FF8277'>
<IconStyle>
<color>ff7782FF</color>
<scale>1.1</scale>
<Icon>
<href>http://www.gstatic.com/mapspro/images/stock/503-wht-blank_maps.png</href>
</Icon>
</IconStyle>
</Style>
</Document>
</kml>
答案 0 :(得分:3)
怎么样:
while (my ($key, $folder) = each %{$myFile->{Document}{Folder}{Placemark}}) {
print $folder->{Point}->{coordinates}."\n";
}
<强>输出:强>
80.2437973022461,13.106230102044576,0.0
80.24688720703125,13.096198508196448,0.0
80.23435592651367,13.094024942328286,0.0
在您的代码中,您正在使用
foreach my $folder (@{$myFile->{Document}->{Folder}->{Placemark}}) {
print $folder->{Point}->{coordinates}."\n";
}
假设$myFile->{Document}->{Folder}->{Placemark}
是对数组的引用。但它不是,它是对哈希的引用,所以你必须通过它和foreach对(key,value)从值中提取坐标。
答案 1 :(得分:3)
我认为我不会使用XML :: Simple。
使用XML :: Twig,这就是你要写的:
#!/usr/bin/perl
use strict;
use warnings;
use 5.10.0; # to get 'say'
use XML::Twig;
XML::Twig->new( twig_roots => { coordinates => sub { say $_->text; } })
->parsefile( $ARGV[0]);
答案 2 :(得分:0)
另一种可能性是使用XML::LibXML
和XPath。 XPath的优点是它们也可用于其他语言,因此其他开发人员可能会理解您的代码。 XPath的缺点是它们的使用在命名空间的存在下不再好用(这就是这里的情况),导致一些看起来很难看的解决方法,比如使用local-name()函数。
以下是一个示例脚本:
use XML::LibXML;
my $doc = XML::LibXML->new->parse_file('ExperimentMap.kml');
for my $coordinate_node ($doc->findnodes('//*[local-name()="coordinates"]')) {
print $coordinate_node->textContent, "\n";
}