2

次の巨大な XML ファイルがあります。

<?xml version="1.0" encoding="utf-16"?>
<!DOCTYPE tmx SYSTEM "56.dtd">
<body>
<tu changedate="20130625T175037Z"">
  <tuv xml:lang="pt-pt">
    <prop type="x-context-pre">&lt;seg&gt;Some text.&lt;/seg&gt;</prop>
    <prop type="x-context-post">&lt;seg&gt;Other text.&lt;/seg&gt;</prop>
    <seg>The text I'm interested.</seg>
  </tuv>
  <tuv xml:lang="it">
    <seg>And it's translation in italian.</seg>
  </tuv>
 </tu> 

 .... followed by other <tu>'s
</body>

ハッシュを使用して「各「セグメント」コンテンツをその変更日付に関連付けます。これにより、ハンドラーを使用して「セグメント」が既に存在するかどうかを確認し、見つかったバージョンが古いかどうかを確認し、古い場合は削除します。このアプローチの問題は、見つかったバージョンが新しい場合、xml ファイルで解析された古いバージョンを削除する方法がないことです。これまでに取得したコードは次のとおりです。

use 5.010;

use strict;
use warnings;

use XML::Twig;
use Digest::MD5 qw(md5);

my $filename = 'pt_PT-it_IT.tmx';
my $out_filename = 'out.xml';
open my $out, '>', $out_filename;
binmode $out;

my $original_twig = new XML::Twig (pretty_print => 'indented', twig_handlers => {tu => \&original_tu});
$original_twig->parsefile($filename);
$original_twig->flush($out);
close $out;

{ my %md5;
sub original_tu {
my($twig, $original_tu) = @_;
#print $original_tu->text;
my $original_seg = $original_tu->first_child('tuv')->first_child('seg')->text;

my $original_changedate = $original_tu->att('changedate');
$original_changedate = substr $original_changedate, 0, 8;
$hash = md5(original_seg);
if (exists($md5{$hash})) {
    if (($md5{$hash}) gt $original_changedate) {
        print "================================\n";
            print "DELETED\n";
            print $original_seg;
            print "\n BECAUSE ORIGINAL DATE: ";
            print $original_changedate;
            print " IS OLDER THAN THE FOUND ONE: ";
            print $other_changedate;
            print "\n=================================\n";
            $original_tu->delete(); 

        }


    }
else
    $md5{$hash} = $original_changedate;
}

}

巨大な (700 MB) XML ファイル内の「changedate」の最新の値を持つ重複を (要約すると) 削除する方法について、事前に光を当てていただきありがとうございます。

ありがとう!

4

1 に答える 1

2

tuとがどのように関連しているかは、私には完全には明らかではありませんseg。したがって、あなたが望むことをしないかもしれないコードを提供するのは難しいです。

ですから、あなたがすでに検討したと確信しているほんの少しのコメントです.2回のパスでこれを行う必要があると思います:

  1. 最初のパスは、各の最新の変更を識別し、segこのデータをハッシュ{ md5 => date }に保存します。すべてtuの場合、作成する方法$md5{$hash}
  2. 次に、2cd パスで、格納された値より低い (または異なる) 値tuを持つすべての を削除します。changedate

ハッシュがメモリに収まるほど小さいことを願っています。1 パス プロセスよりも時間がかかります (そして満足度が低くなります) が、動作するはずです。

于 2013-08-06T16:14:39.510 に答える