2016-08-15 48 views
2

我是一个初学者perl,我有一个问题,我不知道如何解决。我试图从网站获取XML数据并将温度值放入数组中。如何获得perl中的xml值?

这是到目前为止我的代码:

use strict; 
use warnings; 

# For parsing 
use XML::Simple; 

# For downloading 
use LWP::Simple; 

# For debug output 
use Data::Dumper; 

# Turn off output buffering 
$|=1; 

# Note, no error checking here! 

sub main 
{ 

    print "\nDownloading ...."; 
    my $data = get('http://www.yr.no/place/Norway/Telemark/Sauherad/Gvarv/forecast_hour_by_hour.xml'); 

    my $parser = new XML::Simple; 

    print "\nParsing ..."; 
    my $dom = $parser->XMLin($data); 

    print "\n\n"; 

    # Debug output. 
    #print Dumper($dom->{'forecast'}); 

    # Data structure is a hash containing one key, 'entry'. 
    # Get the hash value and cast to an array. 
    my @entries = $dom->{'forecast'}->{'tabular'}->{'time'}; 
    # Go through each array 'entry' element. 
    foreach my $entry(@entries) 
    { 
     print Dumper($entry); 
     # Each element is a hash. 
     # The band name can be got from one hash key. 
     my $tabular = $entry->{'temperature'}; 


     #print "$tabular\n"; 


     print "\n\n"; 
    } 


} 

main(); 

而且,我得到我的终端上的输出:

}, 
     { 
     'temperature' => { 
         'unit' => 'celsius', 
         'value' => '26' 
         }, 
     'windSpeed' => { 
         'name' => 'Light breeze', 
         'mps' => '1.9' 
        }, 
     'to' => '2016-08-17T16:00:00', 
     'pressure' => { 
         'unit' => 'hPa', 
         'value' => '1014.1' 
        }, 
     'from' => '2016-08-17T15:00:00', 
     'precipitation' => { 
          'value' => '0' 
         }, 
     'symbol' => { 
        'numberEx' => '1', 
        'var' => '01d', 
        'number' => '1', 
        'name' => 'Clear sky' 
        }, 
     'windDirection' => { 
          'name' => 'North', 
          'code' => 'N', 
          'deg' => '4.4' 
         } 
     }, 
     { 
     'precipitation' => { 
          'value' => '0' 
         }, 
     'from' => '2016-08-17T16:00:00', 
     'windDirection' => { 
          'name' => 'North-northeast', 
          'code' => 'NNE', 
          'deg' => '20.6' 
         }, 
     'symbol' => { 
        'number' => '1', 
        'name' => 'Clear sky', 
        'var' => '01d', 
        'numberEx' => '1' 
        }, 
     'temperature' => { 
         'unit' => 'celsius', 
         'value' => '27' 
         }, 
     'pressure' => { 
         'value' => '1013.4', 
         'unit' => 'hPa' 
        }, 
     'to' => '2016-08-17T17:00:00', 
     'windSpeed' => { 
         'mps' => '1.2', 
         'name' => 'Light air' 
        } 
     }, 
     { 
     'symbol' => { 
        'numberEx' => '1', 
        'var' => '01d', 
        'name' => 'Clear sky', 
        'number' => '1' 
        }, 
     'windDirection' => { 
          'name' => 'East', 
          'code' => 'E', 
          'deg' => '83.0' 
         }, 
     'from' => '2016-08-17T17:00:00', 
     'precipitation' => { 
          'value' => '0' 
         }, 
     'windSpeed' => { 
         'mps' => '0.7', 
         'name' => 'Light air' 
        }, 
     'pressure' => { 
         'unit' => 'hPa', 
         'value' => '1012.8' 
        }, 
     'to' => '2016-08-17T18:00:00', 
     'temperature' => { 
         'unit' => 'celsius', 
         'value' => '27' 
         } 
     } 
    ]; 
Not a HASH reference at script.pl line 43. 

为什么我得到这个错误,我怎么能取的值温度?提前致谢!

+4

XML :: Simple本身说它不应该用在新代码中。你所看到的是你必须编写代码来迎合XML :: Simple的奇怪之处,然后它不会给出一致的结果,从而破坏你的代码。你应该使用别的东西,比如XML :: Twig或者XML :: LibXML。他们两人的答案可能很快就会出现在这里。 – simbabque

回答

4

XML::Simple告诉你不要使用它。按照其建议。

下面介绍如何使用XML::LibXML提取温度:

#!/usr/bin/perl 

use warnings; 
use strict; 
use feature qw{ say }; 

use XML::LibXML; 

my $dom = 'XML::LibXML'->load_xml(
    location => 'http://www.yr.no/place/Norway/Telemark/Sauherad/Gvarv/forecast_hour_by_hour.xml'); 

for my $temperature ($dom->findnodes('//temperature/@value')) { 
    say $temperature->getValue; 
} 

随着xsh,这是围绕XML的包装::的libxml,你可以只写

open http://www.yr.no/place/Norway/Telemark/Sauherad/Gvarv/forecast_hour_by_hour.xml ; 
for //temperature echo @value ; 
+0

哦,我错过了关于XML :: Simple的那部分内容。这工作!非常感谢! – Nirakander

2

XML::Simple is discouraged

容易得多比你想象的 - 我会建议XML::Twig,因为我认为它有一个更容易的学习曲线:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use XML::Twig; 
use LWP::Simple; 

my $twig = XML::Twig -> parse ( get('http://www.yr.no/place/Norway/Telemark/Sauherad/Gvarv/forecast_hour_by_hour.xml')); 
#print the first temperature value: 
print $twig -> get_xpath('//temperature',0) -> att('value'),"\n"; 

# all the temps in an array: 
use Data::Dumper; 
my @temps = map { $_ -> att('value') } $twig -> get_xpath('//temperature'); 
print Dumper \@temps; 

这里我们利用xpath搜索 - 这有点像XML的正则表达式。 //表示“树中的任何位置”,因此实际上是搜索“温度”节点。 (这似乎适用于您的XML,但您可能需要在其他情况下更具体的路径)。