3

次の形式の巨大なxmlファイルがあります

<XML>
<Application id="1" attr1="some value" attr2="some val"..and many more attr also with nested tags inside application which might contain more attributes
</Application>

<Application id="2"attr1="some value" attr2="some val"..and many more attralso with nested tags inside application which might contain more attributes
</Application>

<Application id="3"attr1="some value" attr2="some val"..and many more attr also with nested tags inside application which might contain more attributes
</Application>

 .... probably 10000 more Application entries
</XML>

各 Application タグにはコンテンツのない属性のみがありますが、属性を持つことができるネストされたタグも含まれており、属性の一部を解析して抽出する必要があります。次のスクリプトを使用しています。アプリケーション タグの小さなサブセットでは問題なく動作しますが、レコードが増えると非常に遅くなります。残念ながら、ファイル全体またはファイル。

これが私のスクリプトです。これをより良く行う方法についての提案は本当にありがたいです。

4

3 に答える 3

2

XML::LibXML::Reader でこれを行うことができると確信していますが、私はそれに慣れていません。XML::Twig でそれを行う方法を次に示します。

Application要素内のデータにアクセスする方法の例を示しました。

 #!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

$filename1 = "exam.xml";

my $parser = XML::Twig->new( twig_handlers => { Application => \&process_application })
                        ->parsefile($filename1);

sub process_application
  { my( $t, $sample)= @_;
    my $hncid    = $sample->att('ID);                     # get an attribute
    my @persons  = $sample->children( 'Person');
    my @aplnamt  = map { $_->att( 'APLN') } @persons;     # that's how you get all attribute values 
    my @students = $sample->findnodes( './Person/Student');
    my @nsschl   = map { $_->att('NS') } @students;
    my @d81      = $sample->descendant('*[@D8CHRG]'); 
    my @d81      = $sample->findnodes('.//*[@D8CHRG]');   # you can use a subset of XPath

    $t->purge;                                           # this is where you free the memory
  }

考えてみると、実際には XML::Twig::XPath を使用して XPath の機能をフルに活用できます。私は XML::Twig のネイティブ ナビゲーション メソッドに慣れているだけです。

于 2013-06-29T08:11:33.240 に答える
1

あなたの問題は、libXML がツリー ベースのパーサーであるため、ドキュメント全体がメモリに読み込まれることだと思います。ストリームベースのパーサーを調査し、必要なものの独自の構造を構築できます

于 2013-06-29T05:00:20.760 に答える
0

ここにテストがあります: 入力 xml ファイル: test2.xml

<?xml version="1.0" encoding="UTF-8"?>
<metabolite>
  <version>3.6</version>
  <creation_date>2005-11-16 15:48:42 UTC</creation_date>
  <update_date>2014-06-11 23:17:42 UTC</update_date>
  <accession>HMDB00001</accession>
  <secondary_accessions>
    <accession>HMDB04935</accession>
    <accession>HMDB06703</accession>
    <accession>HMDB06704</accession>
  </secondary_accessions>
  <name>1-Methylhistidine</name>
</metabolite>

ここに私のPerlスクリプトがあります:parse_hmdb_metabolites_xml.pl

#!/usr/bin/perl -w 

use strict;
use Getopt::Long;
use XML::Simple;

my $usage= "\n$0 
--xml     \t<str>\thmdb xml file
--outf    \t<str>\toutput file
\n";

my($xml,$outf);

GetOptions(
                "xml:s"=>\$xml,
                "outf:s"=>\$outf
);

die $usage if !defined $xml;

print "$xml\n";
my $cust_xml = XMLin($xml);

テスト出力は次のとおりです。

perl parse_hmdb_metabolites_xml.pl  --xml test2.xml
test2.xml
Segmentation fault (core dumped)

テストしますXML::libXML

于 2014-10-11T08:37:38.287 に答える