2016-07-26 6 views
-1

私はXML解析で初心者ですが、Perlを使用してXMLファイルからレポートを作成するコードを作成しましたが、正確な出力が得られないという問題に直面しています。以下は私のファイルです。perlを使ってxmlからレポートを作成する

<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形式の方法でロジックをしたかった。あなたはあなたのロジックをそれに変換できますか? – Paddy

+0

そのヘッダは単なる情報目的です。 – Paddy

関連する問題