使用Perl获取XML数据

时间:2017-12-18 13:37:42

标签: xml perl

我必须获取" Grand Total"的价值。来自xml的值,我已经为它编写了perl脚本,但是对于Grand total的xml标记路径却犯了一些错误。请指导正确的路径。

以下是XML。

<TotalForServiceSummary>
  <GrandTotal><![CDATA[1246.00]]></GrandTotal>
</TotalForServiceSummary>

脚本:

my $salesOrderNumber =s hift @ARGV;
my $billRunID = shift @ARGV;
my $customerNodeID = shift @ARGV;
my $invoiceID = shift @ARGV;
my $billRunDate =shift @ARGV;

my $filename = "So_".$salesOrderNumber."_".$billRunID."_".$customerNodeID."_".$invoiceID."_".$billRunDate;

my $file = `ls /svw/svwsit2b/data/server/invoices/sap_equip_invoice/$filename\*.xml`;

my $return;

open(XML, $file) or die "Cannot open $file for reading: $!\n";

while (my $line = <XML>) {

    if ($line =~ /\<EquipSalesTotalChargeIncTax\>/i) {
        my $xml = new XML::Simple;
        my $ref3 = $xml->XMLin($line);
        $return = $return . $ref3;
    }    
}

1 个答案:

答案 0 :(得分:4)

这里有很多误解。

您不需要一次读取XML文件。您应该让XMLIn()同时处理所有XML - 实际上您可以传递一个文件名,它将打开文件并从中读取所有XML。

但是,您还应该从XML::Simple documentation

中注意这一部分
  

此模块的状态

     

不鼓励在新代码中使用此模块。其他模块是   可用,提供更直接和一致   接口。特别值得推荐的是XML::LibXML   XML::Twig是一个很好的选择。

     

此模块的主要问题是大量选项   (其中一些有不幸的默认值)和任意方式   这些选项相互作用 - 通常会产生意想不到的结果。

     

修补程序包含错误修复和文档修复程序,但是很新   功能不太可能被添加。

您应该认真考虑切换到上面提到的替代库之一。

另外,这两行没有意义:

my $ref3 = $xml->XMLin($line);
$return = $return . $ref3;

$ref3将包含一个引用(可能是一个哈希)。它的字符串表示看起来像HASH(0x12345678),这不太可能是你想要的。

更新:使用XML :: LibXML解决此问题的方法如下所示。但我怀疑你过分简化了你的问题,所以这个解决方案可能不适合你。

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use XML::LibXML;

# My XML is in "total.xml".
my $doc = XML::LibXML->new->parse_file('total.xml');

say $doc->findvalue('//TotalForServiceSummary/GrandTotal');

更新2:关于您的代码的其他几点。

你的台词:

my $salesOrderNumber =shift @ARGV;
my $billRunID = shift @ARGV;

依旧......

最好写成:

my ($salesOrderNumber, $billRunID, $customerNodeID,
    $invoiceID, $billRunDate) = @ARGV;

glob()功能是获取文件名列表的跨平台方式 - 无需使用ls等外部程序。

请使用词法文件句柄和open()的三个arg版本。

open my $xml_fh, '<', $file
  or die "Can't open $file: $!\n";

调用构造函数(new XML::Simple)的“间接对象”方式可能会导致您在某些时候难以发现问题。最好使用XML::Simple->new代替。