2017-02-27 18 views
3

Anydata-0.12を使用してXMLファイルをCSVに変換します。 XMLファイルは次のように探しています:XMLをCSVに変換中にメモリ不足エラーが発生しました

<FIXML r="20030618" s="20040109" v="4.4" xr="FIA" xv="1" xmlns="http://www.fixprotocol.org/FIXML-4-4"> 
<Batch> 
<MktDataFull RptID="23520135" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20171215" MatDt="2017-12-15" CFI="OCASPS" StrkPx="100" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="5.7367" Ccy="USD" PxDelta="0.5" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="30818621" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20180615" MatDt="2018-06-15" CFI="OCASPS" StrkPx="100" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="7.3603" Ccy="USD" PxDelta="0.52" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="31165289" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170317" MatDt="2017-03-17" CFI="OCASPS" StrkPx="101" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="1.7973" Ccy="USD" PxDelta="0.46" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="31165443" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170317" MatDt="2017-03-17" CFI="OCASPS" StrkPx="102" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="1.2775" Ccy="USD" PxDelta="0.35" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="31165368" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170317" MatDt="2017-03-17" CFI="OCASPS" StrkPx="103" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="0.8861" Ccy="USD" PxDelta="0.25" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="31165483" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170317" MatDt="2017-03-17" CFI="OCASPS" StrkPx="104" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="0.5858" Ccy="USD" PxDelta="0.25" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="25807539" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170616" MatDt="2017-06-16" CFI="OCASPS" StrkPx="105" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="1.321" Ccy="USD" PxDelta="0.26" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="30818579" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20180615" MatDt="2018-06-15" CFI="OCASPS" StrkPx="105" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="4.7838" Ccy="USD" PxDelta="0.4" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="32444397" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170616" MatDt="2017-06-16" CFI="OCASPS" StrkPx="106" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="1.0134" Ccy="USD" PxDelta="0.26" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="32868839" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170120" MatDt="2017-01-20" CFI="OCASPS" StrkPx="107" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="0.0079" Ccy="USD" PxDelta="0" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="32444384" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170616" MatDt="2017-06-16" CFI="OCASPS" StrkPx="109" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="0.4888" Ccy="USD" PxDelta="0.11" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
.... 
.... 
</Batch> 
</FIXML> 

CSVファイルはXMLの部分が含まれています。これは、XMLファイルで使用される列ヘッダを持っているし、次のようになります。私はこのコードを実行しています

RptID,BizDt,StrkMult,Sym,StrkValu,Mult,MatDt,CFI,StrkCcy,MMY,StrkPx 
23520135,2016-12-09,1,OEF,100,100,2017-12-15,OCASPS,USD,20171215,100 
30818621,2016-12-09,1,OEF,100,100,2018-06-15,OCASPS,USD,20180615,100 
31165289,2016-12-09,1,OEF,100,100,2017-03-17,OCASPS,USD,20170317,101 
31165443,2016-12-09,1,OEF,100,100,2017-03-17,OCASPS,USD,20170317,102 
31165368,2016-12-09,1,OEF,100,100,2017-03-17,OCASPS,USD,20170317,103 
31165483,2016-12-09,1,OEF,100,100,2017-03-17,OCASPS,USD,20170317,104 
... 

:それは働いていると、テスト目的のために、小さなファイルですべてが正常である

use AnyData; 
my $input_xml = "oc170120.xml"; #name of the XML file 
my $output_csv = "test3.csv"; #name of the output file 
$flags->{record_tag} = 'Instrmt'; 
my $table = adTie('XML', $input_xml, 'r', $flags); 
.... 

。しかし、しばらくして私は得ています

メモリ不足! adtie()は、ファイル全体をメモリに読み込もうとしますが、XMLファイルには400000を超えるレコードがあります。

私は64ビットシステムでPerl 5.24.1を使用しています。

+0

'$ table'を作成した後で何をしていますか? *メモリ不足*この行のエラーまたはデータの操作を行っているテーブルを作成した後ですか? – AbhiNickz

+4

XMLファイルが大きい場合は、XMLファイルをメモリにロードできません。 [XML :: LibXML :: Reader](http://p3rl.org/XML::LibXML::Reader)または[XML :: SAX](http://p3rl.org/)というXMLのストリーミング処理を検索します。 XML :: SAX)。非難されたAnyDataがどちらかを使用できるかどうかはわかりません。 – choroba

+6

XML :: Twigは、チャンク処理でも優れています。 – simbabque

答えて

4

XMLでの問題は、メモリ上では、ディスク上の約10倍の大きさだということを現実的に想定できるということです。

全体を読んでからそれをダンプするのは非常にメモリが不十分で、大きなファイルの場合は見てきたように大きな問題です。

私はXML::Twigが好きです。twig_handlersを使用してファイルを解析して、処理済みのビットを破棄することができるため、この種のタスク(公正でほとんどのXMLタスク - 私は大ファンです)これはメモリのフットプリントを抑えます。あなたの例のためにそう

#!/usr/bin/env perl 

use strict; 
use warnings; 

use XML::Twig; 

my @keys = qw (RptID BizDt Sym StrkValu Mult MatDt CFI StrkCcy MMY StrkPx); 


sub process_data { 
    my ($twig, $data) = @_; 
    # print join ",", map { $data -> get_xpath(".//*[\@$_]",0)-> text } @keys; 

    my %atts = map { %{$_->atts} } $data , $data -> children; 
    print join ",", (map { $atts{$_} // '' } @keys),"\n"; 
    $data -> purge; 
} 

print join ",", @keys, "\n"; 
XML::Twig -> new (twig_handlers => { 'MktDataFull' => \&process_data }) -> parse (\*DATA); 

__DATA__ 
<FIXML r="20030618" s="20040109" v="4.4" xr="FIA" xv="1" xmlns="http://www.fixprotocol.org/FIXML-4-4"> 
<Batch> 
<MktDataFull RptID="23520135" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20171215" MatDt="2017-12-15" CFI="OCASPS" StrkPx="100" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="5.7367" Ccy="USD" PxDelta="0.5" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="30818621" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20180615" MatDt="2018-06-15" CFI="OCASPS" StrkPx="100" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="7.3603" Ccy="USD" PxDelta="0.52" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="31165289" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170317" MatDt="2017-03-17" CFI="OCASPS" StrkPx="101" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="1.7973" Ccy="USD" PxDelta="0.46" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="31165443" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170317" MatDt="2017-03-17" CFI="OCASPS" StrkPx="102" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="1.2775" Ccy="USD" PxDelta="0.35" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="31165368" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170317" MatDt="2017-03-17" CFI="OCASPS" StrkPx="103" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="0.8861" Ccy="USD" PxDelta="0.25" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="31165483" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170317" MatDt="2017-03-17" CFI="OCASPS" StrkPx="104" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="0.5858" Ccy="USD" PxDelta="0.25" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="25807539" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170616" MatDt="2017-06-16" CFI="OCASPS" StrkPx="105" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="1.321" Ccy="USD" PxDelta="0.26" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="30818579" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20180615" MatDt="2018-06-15" CFI="OCASPS" StrkPx="105" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="4.7838" Ccy="USD" PxDelta="0.4" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="32444397" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170616" MatDt="2017-06-16" CFI="OCASPS" StrkPx="106" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="1.0134" Ccy="USD" PxDelta="0.26" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="32868839" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170120" MatDt="2017-01-20" CFI="OCASPS" StrkPx="107" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="0.0079" Ccy="USD" PxDelta="0" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
<MktDataFull RptID="32444384" BizDt="2016-12-09"><Instrmt Sym="OEF" MMY="20170616" MatDt="2017-06-16" CFI="OCASPS" StrkPx="109" StrkMult="1" StrkValu="100" Mult="100" StrkCcy="USD"/><Full Typ="5" Px="0.4888" Ccy="USD" PxDelta="0.11" Dt="2016-12-09"/><Full Typ="D" Px="100.15" Dt="2016-12-09"/></MktDataFull> 
</Batch> 
</FIXML> 

今、あなたはおそらく使用したい:

XML::Twig -> new (...) -> parsefile ('your_xml_file'); 

そしておそらく(への出力は、現時点ではそれが行くだろうとprintにファイルハンドルを開きます

しかし、上記の重要な点は、purgeコールです。これは、XML::Twigで、解析が完了し、メモリから「処理済み」データを削除します。

それで、足もとの足もとが足りないようにしてください。

+0

ありがとうSobrique、それはまさに私が必要なものだ!問題が解決しました – odelys

関連する問題