2016-08-15 9 views
2

私は初心者からPerlまで、私は解決する方法がわからないという問題があります。私はウェブサイトからxml-dataを取り出し、配列の中に温度の値を入れようとしています。これは私のこれまでのコードであるどのようにしてxml値をperlで取得できますか?

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 :: Uniqueの奇妙さに対応するためにコードを作成しなければならず、一貫した結果が得られず、コードが壊れてしまうことです。 XML :: TwigやXML :: LibXMLのようなものを使うべきです。すぐに両方の回答がここに表示されます。 – simbabque

答えて

4

XML::Simpleは使用しないように指示します。そのアドバイスに従ってください。

はここXML::LibXMLを使用して、温度を抽出する方法は次のとおりです。

XMLのラッパーです xsh、::の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; 
} 

、あなただけ書くことができます

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ではうまくいくようですが、他のシナリオではより具体的なパスが必要な場合があります)。

関連する問題