mysql - Perl 和 XPath : missing entries in database table

标签 mysql xml perl xpath mariadb

我想从 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/row1row2 元素位于 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/

相关文章:

php - 在 MySQL 中通过单个查询获取今天、本周、本月和今年的数据?

php - 使用 PHP 生成 XML 签名摘要

jquery - 使用 Catalyst 避免 AJAX 响应中的包装器

java - 是否有任何 Java HTML 解析器生成的节点保留原始文本的索引?

algorithm - 将 (key,value) 数据转换为 csv 格式

java - 如何在同一调试 session 中在 Eclipse 中调试 Java 和 Perl 代码?

使用具有多个条件的 group by 的 MySQL 查询

mysql - 通过索引优化查询

php - Mysql PHP 循环

c# - 使用 StringReader 与 XmlNodeReader 反序列化对象属性