简体   繁体   English

Perl:使用LibXML将XML转换为MySQL

[英]Perl: XML to MySQL with LibXML

I'm pretty new to Perl and i'm writing a perl script to practice and i want to parse info from XML file to MySQL DB , but i'm stuck and i cannot find a way to import the data to MySQL. 我对Perl还是很陌生,我正在编写一个perl脚本来练习,我想将XML文件中的信息解析为MySQL DB,但是我被困住了,我找不到将数据导入MySQL的方法。

Here is my Perl code: 这是我的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;
}

My XML: 我的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 structure: 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    |                |
+------------------+--------------+------+-----+---------+----------------+

If i remove the comment from the print lines the output will be as follow: 如果我从打印行中删除注释,输出将如下所示:

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

As you can see , the main problem is that i have multiple games and i cant seem to find a way to split them so i can import them to mysql. 如您所见,主要问题是我有多个游戏,而且我似乎无法找到一种拆分方法,因此我可以将它们导入mysql。

I would reformulate what you're doing. 我会重新制定你在做什么。 It looks like your table is one row per game not one row per sport. 看起来您的赌桌是每场比赛一排,而不是一项运动每一排。

So you need an 'inner loop' to pick out the game IDs. 因此,您需要一个“内循环”来挑选游戏ID。 Unfortunately - the're not grouped, so you need to do a 'next' sort of operation. 不幸的是-尚未分组,因此您需要执行“下一步”操作。

Using XML::Twig because I'm more familiar with it - something like this: 使用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";
    }    
}

(Pretty sure you can do much the same in XML::LibXML ) (非常确定您可以在XML::LibXML做很多相同的事情)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM