【发布时间】:2016-10-30 09:11:30
【问题描述】:
我正在尝试在 Perl 中解析 CSV 文件并将某些列的信息粘贴到 XML 文件中。我从来没有在 Perl 中做过任何事情,我的想法是将数据存储到一个数组中,然后在构建它时将信息从数组中提取出来。
我确定我做错了几件事,因为我没有得到我期望的值,而是看起来像内存中的数组地址(这里是一个例子:ARRAY(0x35e9360)。
有人可以帮助我并指出更好的解决方案吗?
这里是有问题的代码:
use Text::CSV;
use utf8;
use XML::Simple qw(XMLout);
use XML::Twig;
use File::Slurp;
use Encode;
&buildXML();
my $csv = Text::CSV->new( { binary => 1 } ) # should set binary attribute.
or die "Cannot use CSV: " . Text::CSV->error_diag();
$csv = Text::CSV->new( { sep_char => '|' } );
$csv = Text::CSV_XS->new( { allow_loose_quotes => 1 } );
my $t = XML::Twig->new( pretty_print => indented );
$t->parsefile('output.xml');
$out_file = "output.xml";
open( my $fh_out, '>>', $out_file ) or die "unable to open $out_file for writing: $!";
my $root = $t->root; #get the root
open my $fh, "<:encoding(utf8)", "b.txt" or die "text.txt: $!";
while ( my $row = $csv->getline($fh) ) {
my @rows = $row;
$builds = $root->first_child(); # get the builds node
$xcr = $builds->first_child(); #get the xcr node
my $xcrCopy = $xcr->copy(); #copy the xcr node
$xcrCopy->paste( after, $xcr ); #paste the xcr node
$xcr->set_att( id => "@rows[0]" );
print {$fh_out} $t->sprint();
}
$csv->eof or $csv->error_diag();
这是一个测试文件:
ID|Name|Pos
1|a|265
2|b|950
3|c|23
4|d|798
5|e|826
6|f|935
7|g|852
8|h|236
9|i|642
这是由 buildXML() 子构建的 XML。
<?xml version='1.0' standalone='yes'?>
<project>
<builds>
<xcr id="" name="" pos="" />
</builds>
</project>
【问题讨论】:
-
getline方法返回一个 arrayref ——正如您所说,您看到的是对数组的引用。您需要my @rows = @$row,将其取消引用到一个数组中。至于其余的,你能发一个我可以测试的文件(b.txt)吗? -
还需要
output.xml,除非您打算从头开始编写它(但它的代码是错误的)。 -
在开始测试之前,您确实编写了太多代码,最终产生了许多混淆了整个程序的混乱想法和试用代码。您应该首先编写几行从 CSV 中提取值的行,仅此而已。此外,always
use strict和use warnings 'all'在每个 Perl 程序的顶部。调用子例程时不要使用 & 符号&:只要buildXML()是正确的,如果它告诉你,你用来学习 Perl 的任何资源都非常过时。 -
@zdim 我正在从头开始构建它。有一个子 buildXML。它构建了一个非常简单的结构。我会将其添加到我原来的问题中。