我想从 xml 文件中提取数据并将它们导入到 MariaDB/MySQL 数据库中。 xml 文件是:
<?xml version="1.0" encoding="UTF-8"?>
<database>
<row1s>
<row1 name="fox" category="mammal">
<row2s>
<row2 type="1" size="10"/>
<row2 type="2" size="8"/>
</row2s>
</row1>
<row1 name="horse" category="mammal">
<row2s>
<row2 type="3" size="100"/>
</row2s>
</row1>
<row1 name="bee" category="insect">
<row2s/>
</row1>
<row1 name="wasp" category="insect">
<row2s/>
</row1>
</row1s>
</database>
Perl 代码是:
use strict;
use warnings;
use DBI;
use XML::XPath;
use XML::XPath::XMLParser;
my $xp = XML::XPath->new( filename => "animals4.xml" );
# my $xp = XML::XPath->new( ioref => \*DATA );
my $dbh = DBI->connect( "DBI:mysql:test", "user", "pw", { RaiseError => 1, PrintError => 0 } )
or die "Fehler beim Verbidungsaufbau zum MariaDB-Server:" . " $DBI::err -< $DBI::errstr \n";
for my $row1 ( $xp->findnodes('//row1s/row1') ) {
printf "Level --- row1 \"name\" gives: %s\n", $row1->getAttribute("name");
for my $row2 ( $row1->findnodes('.//row2s/row2') ) {
printf "Level row2 \"type\" gives: %s\n", $row2->getAttribute("type");
printf "Level row2 \"size\" gives: %s\n", $row2->getAttribute("size");
$dbh->do(
"INSERT INTO animal4 (name, category,type,size) VALUES(?,?,?,?)",
undef,
$row1->getAttribute("name"),
$row1->getAttribute("category"),
$row2->getAttribute("type"),
$row2->getAttribute("size")
) or die "Error during execution: " . "$DBI::err -> $DBI::errstr (animal $DBI::state)\n";
}
}
终端输出为:
Level --- row1 "name" gives: fox
Level row2 "type" gives: 1
Level row2 "size" gives: 10
Level row2 "type" gives: 2
Level row2 "size" gives: 8
Level --- row1 "name" gives: horse
Level row2 "type" gives: 3
Level row2 "size" gives: 100
Level --- row1 "name" gives: bee
Level --- row1 "name" gives: wasp
这是我所期望的。但是该表具有以下条目:
name category type size
fox mammal 1 10
fox mammal 2 8
horse mammal 3 100
错过了蜜蜂和黄蜂。谁能帮我解决这个问题?我想知道为什么会发生这种情况,因为终端的输出没问题。
感谢您的帮助。
这是表格的代码:
CREATE TABLE test01.animal4 (
name VARCHAR(50) DEFAULT NULL
, category VARCHAR(50) DEFAULT NULL
, type INTEGER DEFAULT NULL
, size INTEGER DEFAULT NULL
);
这是 hierarchy problem 的后续问题.
最佳答案
您已经有了解释和修复,但我建议进行以下更改
您应该
准备
INSERT INTO
SQL 语句,然后在循环中执行
它。do
的开销要大得多//
(descendant-or-self::node()
) XPath 结构很昂贵,你应该保留它以备不时之需元素将在文档中的位置的想法,这是非常罕见的。在这种情况下,row1
元素位于/database/row1s/row1
而row2
元素位于row2s/row2
相对于那个如果您想在带引号的字符串中使用引号字符,使用不同的定界符会更简洁。例如
"My name is\"$name\""
比qq{My name is "$name"}
要好得多
这是您的程序的一个版本,可能会有所帮助。
use strict;
use warnings;
use XML::XPath;
use DBI;
my $xp = XML::XPath->new( filename => 'animals4.xml' );
my $dbh = DBI->connect(
'DBI:mysql:test', 'user', 'pw',
{ RaiseError => 1, PrintError => 0}
) or die "Fehler beim Verbidungsaufbau zum MariaDB-Server: $DBI::err -< $DBI::errstr\n";
my $insert_animal = $dbh->prepare('INSERT INTO animal4 (name, category, type, size) VALUES (?, ?, ?, ?)');
for my $row1 ( $xp->findnodes('/database/row1s/row1') ) {
my $name = $row1->getAttribute('name');
my $category = $row1->getAttribute('category');
printf qq{Level --- row1 "name" gives: $name\n};
my @row2 = $xp->findnodes('row2s/row2', $row1);
if ( @row2 ) {
for my $row2 ( @row2 ) {
my $type = $row2->getAttribute('type');
my $size = $row2->getAttribute('size');
print qq{Level row2 "type" gives: $type\n};
print qq{Level row2 "size" gives: $size\n};
$insert_animal->execute($name, $category, $type, $size);
}
}
else {
$insert_animal->execute($name, $category, undef, undef);
}
}
输出
Level --- row1 "name" gives: fox
Level row2 "type" gives: 1
Level row2 "size" gives: 10
Level row2 "type" gives: 2
Level row2 "size" gives: 8
Level --- row1 "name" gives: horse
Level row2 "type" gives: 3
Level row2 "size" gives: 100
Level --- row1 "name" gives: bee
Level --- row1 "name" gives: wasp
关于mysql - Perl 和 XPath : missing entries in database table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25702607/