如何在perl中打印空XML元素
我有时需要编写简单的perl脚本,将XML文件中的数据导出到CSV文件中,以便加载到数据库中 我在“打印”一个没有值的元素时遇到了一个问题。它不只是不打印任何内容,而是打印字符串“HASH(0x1ca05f8)”(或其同级) 我如何阻止它这样做 下面是我正在使用的代码和数据。谢谢,--sw parse.pl:如何在perl中打印空XML元素,xml,perl,xml-parsing,Xml,Perl,Xml Parsing,我有时需要编写简单的perl脚本,将XML文件中的数据导出到CSV文件中,以便加载到数据库中 我在“打印”一个没有值的元素时遇到了一个问题。它不只是不打印任何内容,而是打印字符串“HASH(0x1ca05f8)”(或其同级) 我如何阻止它这样做 下面是我正在使用的代码和数据。谢谢,--sw parse.pl: #!/usr/bin/perl #use module use XML::Simple; use Data::Dumper; #create object $xml = new XML:
#!/usr/bin/perl
#use module
use XML::Simple;
use Data::Dumper;
#create object
$xml = new XML::Simple;
#read XML file
$data = $xml->XMLin("$ARGV[0]", ForceArray=>1);
foreach $pr (@{$data->{product}})
{
foreach $rv (@{$pr->{reviews}})
{
foreach $fr (@{$rv->{fullreview}})
{
print "$ARGV[1]", ",";
print "$ARGV[2]", ",";
print "$ARGV[3]", ",";
print "$ARGV[4]", ",";
print $pr->{"pageid"}->[0], ",";
print $fr->{"status"}->[0], ",";
print $fr->{"source"}->[0], ",";
print $fr->{"createddate"}->[0], ",";
print $fr->{"overallrating"}->[0], ",";
print $fr->{"email_address_from_user"}->[0], ",";
foreach $csg (@{$fr->{confirmstatusgroup}})
{
print join(";", @{$csg->{"confirmstatus"}});
}
print "\n";
}
}
}
data.xml:
<?xml version="1.0" encoding="UTF-8"?>
<products xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<product xsi:type="ProductWithReviews" locale="en_US">
<pageid>bshnbat612</pageid>
<reviews>
<fullreview>
<status>Approved</status>
<createddate>2014-03-28</createddate>
<source>email</source>
<confirmstatusgroup>
<confirmstatus>Verified Purchaser</confirmstatus>
<confirmstatus>Verified Reviewer</confirmstatus>
</confirmstatusgroup>
<overallrating>5</overallrating>
<email_address_from_user/>
</fullreview>
</reviews>
</product>
</products>
根据以下建议,以下是翻车机输出:
$VAR1 = {
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'product' => [
{
'xsi:type' => 'ProductWithReviews',
'reviews' => [
{
'fullreview' => [
{
'source' => [
'email'
],
'email_address_from_user' => [
{}
],
'overallrating' => [
'5'
],
'confirmstatusgroup' => [
{
'confirmstatus' => [
'Verified Purchaser',
'Verified Reviewer'
]
}
],
'status' => [
'Approved'
],
'createddate' => [
'2014-03-28'
]
}
]
}
],
'pageid' => [
'bshnbat612'
],
'locale' => 'en_US'
}
]
};
看看可以传递给XML::Simple的选项。没有它,XML::Simple将为空元素提供空哈希。通过调用
XMLin(“$ARGV[0]”,ForceArray=>1,SuppressEmpty=>1)代码>您的输出应为:,,bshnbat612,已批准,电子邮件,2014-03-28,5,,已验证的买方;Verified Reviewer查看可以传递给XML::Simple的选项。没有它,XML::Simple将为空元素提供空哈希。通过调用XMLin(“$ARGV[0]”,ForceArray=>1,SuppressEmpty=>1)代码>您的输出应为:,,bshnbat612,已批准,电子邮件,2014-03-28,5,,已验证的买方;Verified Reviewer查看可以传递给XML::Simple的选项。没有它,XML::Simple将为空元素提供空哈希。通过调用XMLin(“$ARGV[0]”,ForceArray=>1,SuppressEmpty=>1)代码>您的输出应为:,,bshnbat612,已批准,电子邮件,2014-03-28,5,,已验证的买方;Verified Reviewer查看可以传递给XML::Simple的选项。没有它,XML::Simple将为空元素提供空哈希。通过调用XMLin(“$ARGV[0]”,ForceArray=>1,SuppressEmpty=>1)代码>您的输出应为:,,bshnbat612,已批准,电子邮件,2014-03-28,5,,已验证的买方;已验证的审阅者
好的,XML::Simple
文档中有一个很大的提示:
不鼓励在新代码中使用此模块。还提供了其他模块,它们提供了更直观和一致的接口。特别推荐使用XML::LibXML
但就我个人而言,我喜欢XML::Twig
:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
sub print_full_review {
my ( $twig, $full_review ) = @_;
my $pageid =
$twig->root->get_xpath( '/products/product/pageid', 0 )->text;
print join(
",",
@ARGV[ 1 .. 4 ],
$pageid,
$full_review->first_child_text('status'),
$full_review->first_child_text('source'),
$full_review->first_child_text('createddate'),
$full_review->first_child_text('overallrating'),
$full_review->first_child_text('email_address_from_user'),
join( ";",
map { $_->text }
$full_review->first_child('confirmstatusgroup')->children() )
),
"\n";
}
my $twig = XML::Twig->new(
'pretty_print' => 'indented_a',
'twig_handlers' => { 'fullreview' => \&print_full_review }
);
$twig->parsefile( $ARGV[0] );
每当解析器遇到fullreview
元素时,就会触发处理程序的“print\u full\u review”(在树中的任何级别,如果出现问题,您可以将其设置为process/product/products/reviews/fullreview
,从而更具体)
将fullreview
元素传递给此处理程序进行处理
我们从中提取出你所追求的价值
join( ";",
map { $_->text }
$full_review->first_child('confirmstatusgroup')->children() )
是一种稍微复杂一点的方法:
my $confirmstatusgroup = $full_review -> first_child('confirmstatusgroup');
foreach my $confirmstatus ( $confirmstatusgroup -> children ) {
print $confirmstatus -> text,";";
}
但是上面的代码生成了您想要的输出,但是不需要像使用XML::Simple
那样进行任何类型的“suppressempty”捏造 好的,在XML::Simple
文档中有一个很大的提示:
不鼓励在新代码中使用此模块。还提供了其他模块,它们提供了更直观和一致的接口。特别推荐使用XML::LibXML
但就我个人而言,我喜欢XML::Twig
:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
sub print_full_review {
my ( $twig, $full_review ) = @_;
my $pageid =
$twig->root->get_xpath( '/products/product/pageid', 0 )->text;
print join(
",",
@ARGV[ 1 .. 4 ],
$pageid,
$full_review->first_child_text('status'),
$full_review->first_child_text('source'),
$full_review->first_child_text('createddate'),
$full_review->first_child_text('overallrating'),
$full_review->first_child_text('email_address_from_user'),
join( ";",
map { $_->text }
$full_review->first_child('confirmstatusgroup')->children() )
),
"\n";
}
my $twig = XML::Twig->new(
'pretty_print' => 'indented_a',
'twig_handlers' => { 'fullreview' => \&print_full_review }
);
$twig->parsefile( $ARGV[0] );
每当解析器遇到fullreview
元素时,就会触发处理程序的“print\u full\u review”(在树中的任何级别,如果出现问题,您可以将其设置为process/product/products/reviews/fullreview
,从而更具体)
将fullreview
元素传递给此处理程序进行处理
我们从中提取出你所追求的价值
join( ";",
map { $_->text }
$full_review->first_child('confirmstatusgroup')->children() )
是一种稍微复杂一点的方法:
my $confirmstatusgroup = $full_review -> first_child('confirmstatusgroup');
foreach my $confirmstatus ( $confirmstatusgroup -> children ) {
print $confirmstatus -> text,";";
}
但是上面的代码生成了您想要的输出,但是不需要像使用XML::Simple
那样进行任何类型的“suppressempty”捏造 好的,在XML::Simple
文档中有一个很大的提示:
不鼓励在新代码中使用此模块。还提供了其他模块,它们提供了更直观和一致的接口。特别推荐使用XML::LibXML
但就我个人而言,我喜欢XML::Twig
:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
sub print_full_review {
my ( $twig, $full_review ) = @_;
my $pageid =
$twig->root->get_xpath( '/products/product/pageid', 0 )->text;
print join(
",",
@ARGV[ 1 .. 4 ],
$pageid,
$full_review->first_child_text('status'),
$full_review->first_child_text('source'),
$full_review->first_child_text('createddate'),
$full_review->first_child_text('overallrating'),
$full_review->first_child_text('email_address_from_user'),
join( ";",
map { $_->text }
$full_review->first_child('confirmstatusgroup')->children() )
),
"\n";
}
my $twig = XML::Twig->new(
'pretty_print' => 'indented_a',
'twig_handlers' => { 'fullreview' => \&print_full_review }
);
$twig->parsefile( $ARGV[0] );
每当解析器遇到fullreview
元素时,就会触发处理程序的“print\u full\u review”(在树中的任何级别,如果出现问题,您可以将其设置为process/product/products/reviews/fullreview
,从而更具体)
将fullreview
元素传递给此处理程序进行处理
我们从中提取出你所追求的价值
join( ";",
map { $_->text }
$full_review->first_child('confirmstatusgroup')->children() )
是一种稍微复杂一点的方法:
my $confirmstatusgroup = $full_review -> first_child('confirmstatusgroup');
foreach my $confirmstatus ( $confirmstatusgroup -> children ) {
print $confirmstatus -> text,";";
}
但是上面的代码生成了您想要的输出,但是不需要像使用XML::Simple
那样进行任何类型的“suppressempty”捏造 好的,在XML::Simple
文档中有一个很大的提示:
不鼓励在新代码中使用此模块。还提供了其他模块,它们提供了更直观和一致的接口。特别推荐使用XML::LibXML
但就我个人而言,我喜欢XML::Twig
:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
sub print_full_review {
my ( $twig, $full_review ) = @_;
my $pageid =
$twig->root->get_xpath( '/products/product/pageid', 0 )->text;
print join(
",",
@ARGV[ 1 .. 4 ],
$pageid,
$full_review->first_child_text('status'),
$full_review->first_child_text('source'),
$full_review->first_child_text('createddate'),
$full_review->first_child_text('overallrating'),
$full_review->first_child_text('email_address_from_user'),
join( ";",
map { $_->text }
$full_review->first_child('confirmstatusgroup')->children() )
),
"\n";
}
my $twig = XML::Twig->new(
'pretty_print' => 'indented_a',
'twig_handlers' => { 'fullreview' => \&print_full_review }
);
$twig->parsefile( $ARGV[0] );
每当解析器遇到fullreview
元素时,就会触发处理程序的“print\u full\u review”(在树中的任何级别,如果出现问题,您可以将其设置为process/product/products/reviews/fullreview
,从而更具体)
将fullreview
元素传递给此处理程序进行处理
我们从中提取出你所追求的价值
join( ";",
map { $_->text }
$full_review->first_child('confirmstatusgroup')->children() )
是一种稍微复杂一点的方法:
my $confirmstatusgroup = $full_review -> first_child('confirmstatusgroup');
foreach my $confirmstatus ( $confirmstatusgroup -> children ) {
print $confirmstatus -> text,";";
}
但是上面的代码生成了您想要的输出,但是不需要像使用XML::Simple
那样进行任何类型的“suppressempty”捏造 使用数据::转储程序;并打印Dumper$数据以查看它是如何解析XML的。您确实应该避免使用XML::Simple
。它使任何XML代码都比它需要的复杂得多,并引发了各种各样的问题,比如这个问题;和打印转储