perl twig中的属性提取和比较

时间:2014-07-10 19:56:03

标签: xml perl

我有一个大型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,那么我必须提取DIRECTIONROLLROLLNONB的值。另外,我想根据DIRECTION - OI单独列出它们。

如果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

的值

1 个答案:

答案 0 :(得分:0)

NB元素的属性为TICKET时,您试图从HIGHT元素的子元素中提取use strict属性。

始终 use warningsopen位于每个计划的顶部,尤其是您正在寻求帮助。您至少可以检查您的程序是否正确。

您必须总是通过编写类似的内容来测试每个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}}