2016-05-13 76 views
0

我對Perl很新穎,我正在編寫一個perl腳本來練習,並且我想將XML文件中的信息解析爲MySQL DB,但是我卡住了,找不到將數據導入到MySQL的方法。Perl:使用LibXML將XML轉換爲MySQL

這裏是我的Perl代碼:

#!/usr/local/bin/perl 
use strict; 
use warnings; 
use diagnostics; 
use XML::LibXML; 
use DBI; 
my $filename = 'test.xml'; 
my $dom = XML::LibXML->load_xml(location => $filename); 
my $sport_id; 
my $sport_name; 
my $competition_id; 
my $competition_name; 
my $game_id; 
my $game_start; 
my $game_name; 
my @values; 
my $dbh = DBI->connect("dbi:mysql:parser:127.0.0.1", "root", "123qwe", { RaiseError => 1}) or die $DBI::errstr; 
my $query = 'INSERT INTO sports (sport_id,sport_name,competition_id,competition_name,game_id,game_start,game_name) VALUES (?,?,?,?,?,?,?)'; 
my $sth = $dbh->prepare($query) or die "Prepare failed: " . $dbh->errstr(); 

foreach my $test ($dom->findnodes('//Sport')) { 
    print "\n"; 
    $sport_id = $test->findvalue('./ID'); 
    $sport_name = $test->findvalue('./Name'); 
    $competition_id = $test->findvalue('./Competitions/Competition/ID'); 
    $competition_name = $test->findvalue('./Competitions/Competition/Name'); 
    $game_id = $test->findvalue('./Competitions/Competition/Games/ID'); 
    $game_start = $test->findvalue('./Competitions/Competition/Games/Start'); 
    $game_name = $test->findvalue('./Competitions/Competition/Games/Name'); 
    #print "Sport ID: $sport_id\n"; 
    #print "Sport Name: $sport_name\n"; 
    #print "Competition ID: $competition_id\n"; 
    #print "Competition Name: $competition_name\n"; 
    #print "Game ID: $game_id\n"; 
    #print "Game Start: $game_start\n"; 
    #print "Game Name: $game_name\n"; 
    #print "\n"; 
    push @values, $sport_id,$sport_name,$competition_id,$competition_name,$game_id,$game_start,$game_name; 
    $sth->execute(@values) or die $dbh->errstr; 
} 

我的XML:

<Sports> 
<Sport> 
<ID>1369527874</ID> 
<Name>Virtual Football</Name> 
<Competitions> 
<Competition> 
<ID>1374380502</ID> 
<Name>Virtual Football. World - G.Devs Stadium</Name> 
<Games> 
<ID>1974885309</ID> 
<Start>2016-05-11 12:21:00</Start> 
<Name>New England Militia - St. Louis Racers</Name> 
<ID>1974892839</ID> 
<Start>2016-05-11 12:27:00</Start> 
<Name>Las Vegas Rollers - Salt Lake Wrath</Name> 
</Games> 
</Competition> 
</Competitions> 
</Sport> 
<Sport> 
<ID>882</ID> 
<Name>Darts</Name> 
<Competitions> 
<Competition> 
<ID>1834852369</ID> 
<Name>Darts. World - PDC European Tour Outright</Name> 
<Games> 
<ID>1895020486</ID> 
<Start>2016-05-15 23:00:00</Start> 
<Name>PDC European Tour. Outright</Name> 
</Games> 
</Competition> 
</Competitions> 
</Sport> 
</Sports> 

MySQL的結構:

+------------------+--------------+------+-----+---------+----------------+ 
| Field   | Type   | Null | Key | Default | Extra   | 
+------------------+--------------+------+-----+---------+----------------+ 
| id    | int(6)  | NO | PRI | NULL | auto_increment | 
| sport_id   | varchar(255) | YES |  | NULL |    | 
| sport_name  | varchar(255) | YES |  | NULL |    | 
| competition_id | varchar(255) | YES |  | NULL |    | 
| competition_name | varchar(255) | YES |  | NULL |    | 
| game_id   | varchar(255) | YES |  | NULL |    | 
| game_start  | varchar(255) | YES |  | NULL |    | 
| game_name  | varchar(255) | YES |  | NULL |    | 
+------------------+--------------+------+-----+---------+----------------+ 

如果我從打印行刪除註釋輸出將是如下:

Sport ID: 1369527874 
Sport Name: Virtual Football 
Competition ID: 1374380502 
Competition Name: Virtual Football. World - G.Devs Stadium 
Game ID: 19748853091974892839 
Game Start: 2016-05-11 12:21:002016-05-11 12:27:00 
Game Name: New England Militia - St. Louis RacersLas Vegas Rollers - Salt Lake Wrath 


Sport ID: 882 
Sport Name: Darts 
Competition ID: 1834852369 
Competition Name: Darts. World - PDC European Tour Outright 
Game ID: 1895020486 
Game Start: 2016-05-15 23:00:00 
Game Name: PDC European Tour. Outright 

正如你所看到的,主要問題是我有多個遊戲,我似乎找不到一種方法來分割它們,所以我可以將它們導入到MySQL。

+0

爲什麼不只是反覆'//遊戲「而不是? – Sobrique

+0

那麼結果將是相同的,例如第一個體育ID將與價值:19748853091974892839其中包括2體育1974885309和1974892839的身份證,我想分開這些結果。 – user2642601

+0

要點是 - 你的牌桌_看起來像你每場比賽都在尋找一排,而不是每場比賽。 – Sobrique

回答

2

我會重新說明你在做什麼。它看起來像你的表是每遊戲每行不是一行。

所以你需要一個'內部循環'來挑選遊戲ID。不幸的是 - 這個沒有分組,所以你需要做一個'下一個'的操作。

使用XML::Twig因爲我更熟悉它 - 是這樣的:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use XML::Twig; 

my $twig = XML::Twig->parse(\*DATA); 

foreach my $sport ($twig->findnodes('//Sport')) { 
    my %fields; 
    $fields{sport_id}   = $sport->findvalue('./ID'); 
    $fields{sport_name}  = $sport->findvalue('./Name'); 
    $fields{competition_id} = $sport->findvalue('.//Competition/ID'); 
    $fields{competition_name} = $sport->findvalue('.//Competition/Name'); 
    foreach my $game ($sport->findnodes('.//Games/ID')) { 
     $fields{game_id} = $game->text; 
     $fields{game_start} = $game->next_sibling->text; 
     $fields{game_end} = $game->next_sibling->next_sibling->text; 
     print "Fields: ", join(
      ",", 
      @fields{ 
       qw(sport_id sport_name 
        competition_id competition_name 
        game_id game_start game_end) 
      } 
      ), 
      "\n"; 
    }  
} 

(敢肯定你可以做同樣的XML::LibXML