我有一个大型XML文件
</ADDRESS>
</EXTRACT>
</LIST>
<LIST NAME="QWER" PORT_ALIAS="2" ROLL="640" DIRECTION="I">
<EXTRACT>
<ADDRESS>
<HOME ROLLNO="36896" SECTION="A"/>
<HOME ROLLNO="36896" SECTION="B"/>
</ADDRESS>
</EXTRACT>
</LIST>
<LIST NAME="QWER" PORT_ALIAS="3" ROLL="2200" DIRECTION="O">
<HIGHT NB="1" FEE_SUBMIT="FALSE">
<TICKET>
<CLASS SECTION="A" ROLLNO="29582"/>
<CLASS SECTION="B" ROLLNO="29582"/>
</TICKET>
</HIGHT>
</LIST>
<LIST NAME="QWER" PORT_ALIAS="4" ROLL="640"
DIRECTION="I">
<EXTRACT>
<ADDRESS>
<HOME ROLLNO="37556" SECTION="A"/>
<HOME ROLLNO="37556" SECTION="B"/>
</ADDRESS>
</EXTRACT>
</LIST>
我正在使用XML::Twig
从XML数据中提取值。
如果LIST
的第一个孩子是HIGHT
,那么我必须提取DIRECTION
,ROLL
,ROLLNO
和NB
的值。另外,我想根据DIRECTION
- O
或I
单独列出它们。
如果DIRECTION为O
,则所有值将单独打印,以防第一个孩子为HIGHT
OUPUT===> ROLL, ROLLNO, NB
INPUT ==> ROLL, ROLLNO, NB.
use XML::Twig;
my $filename = 'report.txt';
open(my $fh, '>', $filename);
my $phraser = XML::Twig->new(twig_handlers => { LIST => \&process_list, });
$phraser->parsefile("doc.xml");
sub process_list {
my ($twig, $list) = @_;
my $conformation = $list->att('DIRECTION');
my $fee = $list->att('ROLL');
if (defined $list->first_child('HIGHT')) {
foreach my $primary (
$list->first_child('HIGHT')->first_child('TICKET')->children()) {
my $val = $primary->att('NB');
my $group_id = $primary->att('ROLLNO');
if ($conformation eq 'O') {
print $fh "\n output ===> $conformation, $fee, $group_id , $val \n";
}
if ($conformation eq 'I') {
print $fh "\n INPUT Queuing ===> $conformation, $fee, $group_id ,$val \n";
}
}
}
}
close $fh;
print "done\n";
我正在获得这样的输出
output ===> O, 2200, 29582 ,
output ===> O, 2200, 29582 ,
INPUT Queuing ===> I, 500, 29619 ,
INPUT Queuing ===> I, 500, 29619 ,
INPUT Queuing ===> I, 500, 29620 ,
INPUT Queuing ===> I, 500, 29620 ,
output ===> O, 132, 29580 ,
output ===> O, 132, 29580 ,
输出混合。
此外,我无法提取NB
。
答案 0 :(得分:0)
当NB
元素的属性为TICKET
时,您试图从HIGHT
元素的子元素中提取use strict
属性。
始终 use warnings
和open
位于每个计划的顶部,尤其是您正在寻求帮助。您至少可以检查您的程序是否正确。
您必须总是通过编写类似的内容来测试每个open my $fh, '>', $filename or die $!;
来电的成功。
autodie
或者,您可以启用use strict;
use warnings;
use autodie;
use XML::Twig;
my $filename = 'report.txt';
open my $fh, '>', $filename;
my $parser = XML::Twig->new(twig_handlers => { LIST => \&process_list, });
$parser->parsefile('doc.xml');
sub process_list {
my ($twig, $list) = @_;
my $direction = $list->att('DIRECTION');
my $roll = $list->att('ROLL');
my $hight = $list->first_child('HIGHT') or return;
my $ticket = $hight->first_child('TICKET') or return;
my $nb = $hight->att('NB');
for my $primary ($ticket->children) {
my $rollno = $primary->att('ROLLNO');
printf $fh "\n%s ===> %d, %d, %d\n",
$direction eq 'O' ? 'output' : 'INPUT Queuing',
$roll,
$rollno,
$nb;
}
}
close $fh;
print "done\n";
编译指示,为您执行此操作。
我建议您查看XML::Path
模块,这样可以更轻松地访问XML数据。
这个程序可以做你想做的事。
{{1}}