2016-07-26 134 views
-1

我是XML解析中的新手,我使用Perl制作了一个从XML文件构建报告的代码但是我面临的问题是没有得到确切的输出结果。以下是我的文件。从xml使用perl构建报告

<ROOT> 
<BILL id = '1'> 
    <CHARGES ChargeCategoryDescription="MAYESEVILLE CHARGES" Amount="70.09" Parent="1"/> 
    <CHARGES ChargeCategoryDescription="MA - WATER" Amount="43.04" Parent="0"> 
     <LineItemDetail UtilityTransDetailID="6605683" ComponentType="Flat Rate" ComponentDescription="WATER MIN"> 
      <LIDetailConsumption PreviousRead="914.0000000" CurrentRead="915.0000000" ActualConsumption="1.0000000"/> 
     </LineItemDetail> 
    </CHARGES> 
    <CHARGES ChargeCategoryDescription="MA - SEWER" Amount="27.05" Parent="0"> 
     <LineItemDetail UtilityTransDetailID="6605685" ComponentType="Flat Rate" ComponentDescription="SEWER MINIMUM"> 
      <LIDetailConsumption PreviousRead="91.0000000" CurrentRead="95.0000000" ActualConsumption="4.0000000"/> 
     </LineItemDetail> 
    </CHARGES>  
</BILL> 
<BILL id = '2'> 
    <CHARGES ChargeCategoryDescription="MAYESEVILLE CHARGES" Amount="21.52" Parent="1"/> 
    <CHARGES ChargeCategoryDescription="MA - WATER" Amount="21.52" Parent="0"> 
     <LineItemDetail UtilityTransDetailID="6605690" ComponentType="Flat Rate" ComponentDescription="WATER MIN"> 
      <LIDetailConsumption PreviousRead="790.0000000" CurrentRead="791.0000000" ActualConsumption="1.0000000"/> 
     </LineItemDetail> 
    </CHARGES>  
</BILL> 
<BILL id = '3'> 
    <CHARGES ChargeCategoryDescription="MAYESEVILLE CHARGES" Amount="60.7" Parent="1"/> 
    <CHARGES ChargeCategoryDescription="MA - WATER" Amount="38" Parent="0"> 
     <LineItemDetail UtilityTransDetailID="6605673" ComponentType="Flat Rate" ComponentDescription="WATER MIN"> 
      <LIDetailConsumption PreviousRead="5.0000000" CurrentRead="5.0000000" ActualConsumption=".0000000"/> 
     </LineItemDetail> 
    </CHARGES> 
    <CHARGES ChargeCategoryDescription="MA - SEWER" Amount="22.7" Parent="0"> 
     <LineItemDetail UtilityTransDetailID="6605675" ComponentType="Flat Rate" ComponentDescription="SEWER MINIMUM"> 
      <LIDetailConsumption PreviousRead="5.0000000" CurrentRead="5.0000000" ActualConsumption=".0000000"/> 
     </LineItemDetail> 
    </CHARGES>  
</BILL> 

以下是我的代码

use XML::Twig; 

my $filename = "sample.xml"; 

my $twig = XML::Twig->new(); 
$twig->parsefile($filename); 
my $root = $twig->root; 

open(OUT, ">output.txt") or die "$!"; 

foreach my $bill($root->children('BILL')) 
{ 
    $Field[0] = $bill->att('id'); 
    foreach my $service($bill->children('CHARGES')) 
    {  
     $Field[1] = $service->att('ChargeCategoryDescription'); 
     if ($Field[1] =~ /MA \- WATER/) 
     { 
      $Field[1] = $service->att('ChargeCategoryDescription'); 
     } 
     elsif ($Field[1] =~ /MA \- SEWER/) 
     { 
      $Field[1] = $service->att('ChargeCategoryDescription'); 
     } 
     $Field[2] = $service->att('Amount'); 
     foreach my $read ($service->children('LineItemDetail')) 
     { 
      $Field[3] = $read->first_child('LIDetailConsumption')->att('CurrentRead'); 
      $Field[4] = $read->first_child('LIDetailConsumption')->att('PreviousRead'); 
      $Field[5] = $read->first_child('LIDetailConsumption')->att('ActualConsumption'); 
     } 

    } 
    push(@servicearr,"$Field[1] $Field[3] $Field[4] $Field[5] $Field[2]"); 
    if (@servicearray>7){die "MORE THEN TWO SERVICES FOUND IN ID#$Field[0] \n";} 
    write OUT; 
    @servicearr =(); 

} 

format OUT = 
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 

@<<<<<<<<<<<<<<<<< 
$Field[0] 


@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
$servicearr[0] 
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
$servicearr[1] 
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
$servicearr[2] 


. 

我想要的输出如下如下:


Bill No: 1 

Service   CurrentRead  PreviousRead Consumption  Amount 
MA - WATER  915.0000000  914.0000000  1.0000000  43.04 
MA - SEWER  95.0000000  91.0000000  4.0000000  27.05 


Bill No: 2 

Service   CurrentRead  PreviousRead Consumption  Amount 
MA - WATER  791.0000000  790.0000000  1.0000000  21.52 


Bill No: 3 

Service   CurrentRead  PreviousRead Consumption  Amount 
MA - WATER  5.0000000  5.0000000  .0000000  38 
MA - SEWER  5.0000000  5.0000000  .0000000  22.7 

请需要帮助,在先进的感谢。

+2

你有什么问题? – Sobrique

回答

0

为了让您的输出,我可能会解决它像这样:

#!/usr/bin/perl 
use strict; 
use warnings 'all'; 

use XML::Twig; 

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

my @headers = qw (CurrentRead PreviousRead ActualConsumption); 
my @categories = ('MA - WATER', 'MA - SEWER'); 

open (my $output, '>', "output.txt") or die $!; 
foreach my $bill ($twig -> get_xpath('//BILL')) { 
    print {$output} "Bill ID: ", $bill -> att('id'),"\n\n"; 
    print {$output} join "\t", "Service\t", @headers, "\n"; 
    foreach my $category (@categories) { 
     my $charge = $bill -> get_xpath(".//CHARGES[\@ChargeCategoryDescription=\"$category\"]", 0); 
     next unless $charge; 
     print {$output} join "\t", $category, (map { $charge -> get_xpath('.//LIDetailConsumption',0) -> att($_) } @headers), "\n"; 
    } 
    print {$output} "\n"; 

} 

注 - 用制表位delinate格式,而不是格式。这不是你要求的,我知道,但IMO更有用。

+0

我非常感谢你的回答,但我想像perl格式一样采用perl格式的逻辑,获取元素值并将其转换为格式。请你可以把你的逻辑转换成那个...... – Paddy

+0

这个标题只是信息的目的,我不需要我只关心值。 – Paddy