2011-10-12 9 views
6

私は次のような問題があります:私は非常に大きなXMLファイル(300 + Megsなど)を持っており、DBに値の一部を追加するために解析する必要があります。これらのファイルの構造も非常に複雑です。 Stax Parserを使用したいのは、一度にXMLファイルの一部のみをプ​​ル・パース(そして処理)することで、メモリ全体をロードするのではなく、 Stax(少なくともこれらのXMLファイル)は面倒です、私は大量のコードを書く必要があります。 XMLファイルをJavaオブジェクト(JAX-Bのようなもの)にマーシャリングすることができれば、この後者の観点から私は非常に助けになります。しかし、これはファイル全体とメモリ内の大量のObjectインスタンスを一度に読み込みます。非常に大きなXMLファイルの解析とJavaオブジェクトへのマーシャリング

私の質問は、ファイルを順番に解析(または部分的に解析)し、それらの部分だけをJavaオブジェクトにマーシャリングする方法があるため、メモリに邪魔されることなく簡単に処理できますか?

答えて

2

まあ、最初のオフ、私は私の質問に答える二人に感謝したい、しかし、それらの提案技術は少し遠くJavaからしてみましょうされているので、私は最終的には、部分的にこれらの提案を使用していないことになりました「標準的なXML解析」と言います。これまでのところ、Javaに既に存在する同様のツールが存在する場合、また実際にはこれを達成するためにJava APIのみを使用するソリューションが見つかったため、これまでのところ気分が変わっています。

私はすでに実装を完了しているので、私が見つけた解決策はあまり詳しく説明しませんが、ここに配置するコードはかなり大きなチャンクです(私はSpring Batchをその上に使い、設定やもの)。

がここで大きなアイデアは、XML文書を持っており、それは、XSDスキーマに対応するなら、あなたが&マーシャルそれを解析することができるという事実である:

私は、しかし、私はついにやってしまったものを上に小さなコメントを行いますJAXBを使用することができます。チャンクはSTAXなどの偶数パーサーで読み取ってからJAXB Marshallerに渡すことができます。

これは実質的に、XMLファイルのどこに「ここにはたくさんの繰り返し構造があり、一度に1つずつ繰り返します」と言うことができる場所をまず決定する必要があることを意味します。これらの繰り返し部分は、通常、同じタグ(子タグ)が親タグ内で多く繰り返されます。だから、JAXBにその子タグの内容をストリームし、JAXBでマーシャリングして処理するよりも、それぞれの子タグの開始時にトリガーされるイベントリスナーをSTAXパーサに作成するだけです。

本当にこのアイデアは、私が従った(この記事は2006年のものですが、JDK 1.6を扱っていましたが、当時はかなり新しく、バージョンではそれほど古いものではありません)。

http://www.javarants.com/2006/04/30/simple-and-efficient-xml-parsing-using-jaxb-2-0/

+0

あなたの問題が解決されたことを知ってよかったです。これは私が投稿したものとはどのように違うのですか? – Kashyap

+0

まあ、正直言って、それは大きなフレームワークの一部の恐怖でした:)(どちらも悪く残念です)。まず、EMFはかなり複雑なフレームワークのようですが、XML処理だけではなく、他の多くのもののために、私はいつも可能な限り重いフレームワークを避けようとしています(これは単なる個人的好みです。一般的にそれをするのは悪いと言っている)。第2に、私は怠惰であり、EMFは非標準のXML解析APIを使用しています。これは標準のJava XML APIを使用してソリューションを選んだためです。 –

+1

実際、EMFが好きか否かにかかわらず、私はそれを使用しないことをお勧めします(「** EMFはそのような小さな問題の大きなハンマーです**」)。そして、パーサーをもう一度引用するために "**あなたが欲しいものを何でも使用して解析します**、ループ内でのStringStreamか何かを作成し、** JAX-BまたはEMFに渡します**" – Kashyap

5

Eclipse EMFをお勧めします。しかし、それは同じ問題を抱えています。ファイル名を指定すると、全体を解析します。どのくらいの量が読み込まれているかを減らすためのオプションがいくつかありますが、96 GBのRAMを搭載したマシンでは気にしませんでした。 :)

とにかく、あなたのXMLフォーマットがよく定義されている場合、1つの回避策は、ファイル全体をいくつかのより小さい(しかしまだよく定義された)XMLスニペットに分解することでEMFをだますことです。次に、それぞれのスニペットを順にフィードします。私はJAX-Bを知らないが、おそらく同じ回避策をそこに適用することもできる。 EMFはこのような小さな問題のために大きすぎるハンマーなので、私はお勧めします。

あなたのXMLは次のように見える場合だけ少し詳しく説明する:

<tag1> 
    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 

    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 
............ 
    <tag2> 
     <tag3/> 
     <tag4> 
      <tag5/> 
     </tag4> 
     <tag6/> 
     <tag7/> 
    </tag2> 
</tag1> 

そして、それは、それぞれが<tag2>で始まり、</tag2>で終わる1つのXMLに分けることができます。そして、ほとんどのパーサーはストリームを受け入れますので、必要なものを使用して解析し、ループ内の各<tag2>のStringStreamなどを作成し、JAX-BまたはEMFに渡します。

HTH

+0

これは素晴らしいサウンドと私は(:)今ここでの深夜)明日最初の事をしようとするでしょうというものです。この提案をお寄せいただきありがとうございます。 –

+1

@thekashyapです。私はそれらのマシンの一つ、プレゼーを持つことができますか?一つだけ! –

+0

Hehe ..それらは私たちのテストマシンです、私は他の人のように4GBのWin7ラップトップで働いています。:) – Kashyap

1

ここでは、ドキュメントの投影が回答になる場合があります。 Saxonと他の多くのXQueryプロセッサーはこれをオプションとして提供しています。大規模なドキュメントから少量のデータを選択する合理的に単純なクエリがある場合、クエリプロセッサはクエリを分析して、ツリーのどの部分がクエリに使用可能である必要があり、処理中に破棄できるかを決定します。結果として得られるツリーは、多くの場合、ドキュメント全体のサイズのわずか1%にすぎません。ここにサクソンのための詳細:

http://saxonica.com/documentation/sourcedocs/projection.xml

関連する問題