使用Perl获取XML数据

使用Perl获取XML数据

问题描述:

我必须从xml中获取“总计”值的值,我已经为它编写了perl脚本,但是对于总计xml标记路径已经发生了一些错误。请指导正确的路径。使用Perl获取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

我已经修复了你的代码的格式(这包括添加缺少的结束'}')。不客气,但请在将来自己做。如果您要求一群陌生人阅读并理解您的代码,那么尽可能简单地为他们完成该任务只是礼貌。 –

+1

显而易见的错误是,示例输入与代码中的内容不匹配 –

+1

*“我...对于总计xml标记路径发生了一些错误”*但是您的代码不显示任何“XML标签路径”。您需要展示您的真实代码和数据才能获得适当的帮助。 – Borodin

有相当多的误解回事。

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

但是,你也应该注意从XML::Simple documentation本节:

STATUS这个模块

使用本模块中新代码是不鼓励的。其他模块是 可用,提供更直接和一致的 接口。特别强烈建议XML::LibXMLXML::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; 

的​​3210函数是一个跨平台的方式来获得文件名列表 - 无需使用外部程序像ls

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

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

调用构造函数(new XML::Simple)的“间接对象”的方式将有可能导致你难以找到在某一点问题。代替使用更好。

+0

由于OP代码正在查找包含“EquipSalesTotalChargeIncTax”标签的行,因此不确定您的第一次更新是否完全正确 –

+0

@ChrisTurner:是的,我基于样本数据而不是代码。这就是为什么我说我认为他已经过分简化了这个问题(并且可能在这个过程中让自己感到困惑)。 –

+0

感谢Chris&Dave提供了所有的建议和帮助,你们的人是对的,我试图过分简化它,因为示例给出的是一个非常大的XML文件的一部分,也有很多'GrandTotal'标签,但我需要获取一个在之下。 – Vijay