【发布时间】:2018-06-04 09:02:36
【问题描述】:
这可能需要一些时间来解释,但我有一个文件 (XMLList.txt),其中包含多个 IDOC XML 的路径。 XMLList.txt 的内容如下所示:
/usr/local/sterlingcommerce/data/archive/SFGprdr/SFTPGET/2017/Dec/week_4/AU_DHL_PW_Inbound_Delivery_from_Pfizer_20171220071754.xml /usr/local/sterlingcommerce/data/archive/SFGprdr/SFTPGET/2017/Dec/week_4/AU_DHL_PW_Inbound_Delivery_from_Pfizer_20171220083310.xml /usr/local/sterlingcommerce/data/archive/SFGprdr/SFTPGET/2017/Dec/week_4/CCMastOut_MQ_GLB_1_20171220154826.xml
我正在尝试创建一个 Perl 脚本,该脚本读取每个 XML 并将每个 XML 文件中的标签 DOCNUM、SNDPRN 和 RCVPRN 的值解析为管道分隔文件“report.csv”
另外需要注意的是,我的 XML 文件可能是: 全部在一行 - 示例
<?xml version="1.0" encoding="UTF-8"?><ZDELVRY073PL><IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1"><TABNAM>EDI_DC40</TABNAM><MANDT>400</MANDT>
<DOCNUM>0000000443474886</DOCNUM><DOCREL>731</DOCREL><STATUS>30</STATUS>
<DIRECT>1</DIRECT><OUTMOD>4</OUTMOD><IDOCTYP>DELVRY07</IDOCTYP>
<CIMTYP>ZDELVRY073PL</CIMTYP><MESTYP>ZIBDADV</MESTYP><MESCOD>IBG</MESCOD>
<SNDPOR>SAPQ01</SNDPOR><SNDPRT>LS</SNDPRT><SNDPRN>Q01CLNT400</SNDPRN>
<RCVPOR>XMLDIST_MT</RCVPOR><RCVPRT>LS</RCVPRT><RCVPFC>LS</RCVPFC>
<RCVPRN>AU_DHL</RCVPRN>.... </EDI_DC40></IDOC>
或多行 XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<INVOIC02>
<IDOC>
<EDI_DC40>
<TABNAM/>
<DOCNUM>0000000658056255</DOCNUM>
<DIRECT/>
<IDOCTYP>INVOIC02</IDOCTYP>
<MESTYP>INVOIC</MESTYP>
<SNDPOR>SAPP01</SNDPOR>
<SNDPRT/>
<SNDPRN>ALE400</SNDPRN>
<RCVPOR>XMLINVOICE</RCVPOR>
<RCVPRT>KU</RCVPRT>
<RCVPRN>C18BASWARE</RCVPRN>
<CREDAT>20171220</CREDAT>
<CRETIM>222323</CRETIM>
</EDI_DC40>
到目前为止,我使用的脚本似乎适用于小型 XML。但是,某些 > 50 MB 的 XML 会引发此错误:
内存不足!记不清!回调调用退出 /usr/opt/perl5/lib/site_perl/5.10.1/XML/SAX/Base.pm 第 1941 行 (#1) (F) 通过 call_sv() 从外部包调用的子程序 调用exit退出。
内存不足!
所以,这是我正在使用的代码。希望您能帮忙调整一下:
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
# use module
use XML::Simple;
use Data::Dumper;
# create object
my $xml = new XML::Simple;
my $file_list = 'XMLList.txt';
open(my $fh_i, '<:encoding(UTF-8)', $file_list)
or die "Could not open file '$file_list' $!";
my $csv_out = 'report.csv';
open(my $fh_o, '>', $csv_out)
or die "Could not open file '$csv_out' $!";
while (my $row = <$fh_i>) {
$row =~ s/\R//g;
my $data = $xml->XMLin($row);
print $fh_o "$data->{IDOC}->{EDI_DC40}->{DOCNUM}|";
print $fh_o "$data->{IDOC}->{EDI_DC40}->{SNDPRN}|";
print $fh_o "$data->{IDOC}->{EDI_DC40}->{RCVPRN}\n";
}
close $fh_o;
【问题讨论】:
-
如果我需要处理无法放入内存的文档,我会使用 XML::LibXML::Reader(及其
copyCurrentNode(1))或 XML::Twig(使用 @987654325 @)。 -
当你在同一个对象上多次调用
XMLin时,我不知道XML::Simple会做什么。但是,在调用XMLin之前将my $xml = XML::Simple->new内部 移动到while循环中可能会有所收获。
标签: perl xml-parsing xml-simple