2

CSV に変換する必要がある巨大な XML ファイル (約 10 Gb) があります。このファイルには、多数の顧客に関する情報が含まれています。CSV形式に変換する必要があります。問題は、多くの顧客が他の顧客が使用しない余分なフィールドを持ち、一部のフィールドが繰り返されることです。XML の例は次のとおりです。

<customer>
<customerID>1</customerID>
    <auc>
        <algoId>0</algoId>
        <kdbId>1</kdbId>
        <acsub>1</acsub>
    </auc>
</customer>

<customer>
<customerID>2</customerID>
    <auc>
        <algoId>0</algoId>
        <kdbId>1</kdbId>
        <acsub>1</acsub>
        <extraBit>12345</extraBit>
    </auc>
    <auc>
        <algoId>2</algoId>
        <kdbId>3</kdbId>
        <acsub>3</acsub>
        <extraBit>67890</extraBit>
    </auc>
        <customOptions>
            <odboc>0</odboc>
    <odbic>0</odbic>
    <odbr>1</odbr>
    <odboprc>0</odboprc>
    <odbssm>0</odbssm>
</customOptions>
</customer>

ご覧のとおり、最初の顧客には auc ブロックが 1 つしかありませんが、2 番目の顧客には 2 つの auc ブロックがあり、さらに、extraBit である auc に余分なタグもあります。今質問:

  1. 一度に 1 人の顧客を処理する必要があります (1 人の顧客から /customer へ、など)。10 Gb を一度に処理するとシステムがクラッシュします。

  2. XML TWIG をループで使用しようとしましたが、Customer 1 の extraBit を使用しようとすると、「未定義の値」のためにプログラムが終了します。

    print $customer->first_child('extraBit')->text()

    xml-tags.pl の 50 行目で未定義の値に対してメソッド "text" を呼び出すことはできません。

  3. 顧客の追加の auc 値については、次のように CSV ファイルに出力する必要があります。

    customerID,algoId,kdbId,acsub,extraBit,algoId2,kdbId2,acsub2,extraBit2

    1,0,1,1,,,,,,

    2,0,1,1,1234,2,3,3,67890

4

1 に答える 1

3
print $customer->first_child('extraBit')->text()

first_child_text一致する子要素が見つからない場合に空の文字列を返すように定義されている代わりに使用することで、未定義のエラーを回避できます。

print $customer->first_child_text('extraBit')

完全なコードは次のようになります

my $t= XML::Twig->new(
  twig_handlers => { customer => \&process_customer });
$t->parsefile('file.xml');

sub process_customer {
  my ($t, $customer) = @_;
  print $customer->first_child_text('customerID');
  foreach my $auc ($customer->children('auc')) {
    print ',', $auc->first_child_text('algoId'),
          ',', $auc->first_child_text('kdbId'),
          ',', $auc->first_child_text('acsub'),
          ',', $auc->first_child_text('extraBit');
  }
  print "\n"
  $customer->purge;
}
于 2013-02-26T15:30:36.890 に答える