如何使用UNIX命令行将XML转换为MYSQL插入?

时间:2014-11-22 16:19:58

标签: mysql xml bash perl unix

如果我有一个看起来像这样的XML

<monsterload xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<monster>
<idLore_Monsters>99</idLore_Monsters>
<strMonsterName>Young Minotaur</strMonsterName>
<strDescription>Not quite as experienced as an older Minotaur warrior, young Minotaurs are still quite dangerous and guard their treasure with equal ferocity if not strength.</strDescription>
<intLevel>20</intLevel>
<intExp>35</intExp>
<intGold>18</intGold>
<intBaseHP>301</intBaseHP>
<intBaseMP>100</intBaseMP>
<intBaseSP>30</intBaseSP>
<intSTR>35</intSTR>
<intDEX>35</intDEX>
<intINT>0</intINT>
<intCHA>0</intCHA>
<intEND>30</intEND>
<intLUK>0</intLUK>
<strExtraData>minotaur,lean:1.5</strExtraData>
<idLore_Elements>3</idLore_Elements>
<idLore_WeaponTypes>1</idLore_WeaponTypes>
<intWeaponBaseDamage>4</intWeaponBaseDamage>
<intWeaponRandDamage>3</intWeaponRandDamage>
<intWeaponBonusToHit>12</intWeaponBonusToHit>
<intArmorFIRE>115</intArmorFIRE>
<intArmorWATER>85</intArmorWATER>
<intArmorICE>85</intArmorICE>
<intArmorWIND>130</intArmorWIND>
<intArmorEARTH>70</intArmorEARTH>
<intArmorENERGY>115</intArmorENERGY>
<intArmorLIGHT>100</intArmorLIGHT>
<intArmorDARKNESS>100</intArmorDARKNESS>
<intArmorMELEE>25</intArmorMELEE>
<intArmorRANGED>15</intArmorRANGED>
<intArmorMAGIC>15</intArmorMAGIC>
<strBodyFileName>monster-minotaur5.swf</strBodyFileName>
<strHeadFileName>monster-minotaur2-head.swf</strHeadFileName>
<idLore_Backgrounds>5</idLore_Backgrounds>
<intMaxPackSize>2</intMaxPackSize>
<dateMonsterUpdated>2013-11-18T21:15:23</dateMonsterUpdated>
<strWeaponElement>Earth</strWeaponElement>
<strWeaponType>Melee</strWeaponType>
<strBackgroundTerrain>dungeon</strBackgroundTerrain>
<strBackgroundFileName>background-dungeon2.swf</strBackgroundFileName>
<intPower>100</intPower>
<numPower>1.000000</numPower>
</monster>
</monsterload>

我可以用这个做出MYSQL插入语句吗? (自动地)。我现在做的是将其转换为csv,然后使用在线工具将csv转换为MYSQL,这非常慢。 这是一个示例SQL代码,前几行:

 INSERT INTO `tablename` (`IdLore_Monsters`, `strMonsterName`, `strDescription`, `Level`))
 VALUES
(99, 'Young Minotaur', 'Not quite as experienced as an older Minotaur warrior, young Minotaurs are still quite dangerous and guard their treasure with equal ferocity if not strength.', '20');

1 个答案:

答案 0 :(得分:1)

l0b0是正确的。你真的应该努力自己解决这个问题,而不是简单地希望从云中的一些匿名专家那里获得免费的解决方案。但是在这种情况下,你很幸运,因为我喜欢写一些代码来做这件事。

最好记住Stack Overflow 不是论坛,其主要目的不是为每个人提供支持&#39困难,但建立一个普遍适用的常见编程问题解决方案库。这意味着应该是我最不关心的问题,我应该专注于创建尽可能通用的答案。考虑到这一点,当您提出问题时最好更加谦虚,并且您应该首先在网站上搜索您可以在您的情况下使用的先前解决方案。

总是始终最好使用适当的XML解析模块来处理XML。我的示例显示了使用XML::Twig的解决方案,该解决方案不是核心模块,可能需要安装。

我编写了一个辅助子程序,用于猜测数据项是否应该被引用,具体取决于它是否&#34;看起来像一个数字&#34;。如果您使用DBI来操作数据库,那么在传递给prepare的SQL语句中使用占位符会好得多,并在调用中提供实际值到execute

use strict;
use warnings;

use XML::Twig;
use Scalar::Util qw/ looks_like_number /;

my $twig = XML::Twig->new;
$twig->parsefile('monsterload.xml');

my @columns = qw/ idLore_Monsters strMonsterName strDescription intLevel /;

for my $monster ($twig->get_xpath('/monsterload/monster')) {
  printf "INSERT INTO `tablename` (%s)\nVALUES (%s)\n",
      join(', ', map "`$_`", @columns),
      join(', ', map monster_field($monster, $_), @columns);
}

sub monster_field {
  my ($monster, $field_name) = @_;

  my $value = $monster->field($field_name);
  $value = "'$value'" unless looks_like_number($value);
  $value;
}

<强>输出

INSERT INTO `tablename` (`idLore_Monsters`, `strMonsterName`, `strDescription`, `intLevel`)
VALUES (99, 'Young Minotaur', 'Not quite as experienced as an older Minotaur warrior, young Minotaurs are still quite dangerous and guard their treasure with equal ferocity if not strength.', 20)