【问题标题】:Building report from xml using perl使用 perl 从 xml 构建报告
【发布时间】:2016-11-29 22:58:11
【问题描述】:

我是 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

需要帮助,在此先感谢。

【问题讨论】:

  • 您遇到了什么问题?

标签: xml perl xml-twig


【解决方案1】:

为了得到你的输出,我可能会这样处理它:

#!/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";

}

注意 - 使用制表位来划分格式,而不是格式。我知道,这不是您所要求的,但 IMO 它更有用。

【讨论】:

  • 非常感谢您的回答,但我想要 perl 格式的逻辑,就像我一样,获取元素值并放入格式中。请你把你的逻辑转换成那个......
  • 标题只是信息目的,我不需要我只关心价值观。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
  • 2022-11-17
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多