大量の非常に大きな XML ファイルを処理し、各要素を深さ優先で読み取る必要があります。サイズが原因で、どのようなDOM
解決策も論外であり、必要な実際の要素が「リーフ」ではなくその親であるという事実によって、事態はさらに複雑になります。
より具体的には、ファイルは次のような構造を持っています
<Level 1>
...
<Level 2>
...
<Level N-1>
<value>...</value>
<value>...</value>
...
<value>...</value>
</Level N-1>
<Level N-1>
<value>...</value>
<value>...</value>
...
<value>...</value>
</Level N-1>
...
<Level N-1>
<value>...</value>
<value>...</value>
...
<value>...</value>
</Level N-1>
...
</Level 2>
</Level 1>
上記のような各ファイルから、<Level N-1>
要素を個別に読み取る必要があります (それぞれに対応するすべての<value>
要素が含まれます)。深さ はN
、各ファイル内およびファイル間で異なるため、XML
タグ名と同様に本質的に不明です。より高いレベルにも要素が存在するという事実によって、事態はさらに複雑<value>
になります (つまり、それらLevel N
は達成された保証を構成するものではありません)。
特定の深さで XML 要素全体を文字列として読み取るための簡単な解決策は、次のようなものです。
int level = 0; // The base level of the element, could be at any depth
Reader in = ... // The reader to the input
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
PrintStream out = new PrintStream(outStream);
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(in);
XMLEventWriter writer = XMLOutputFactory.newInstance().createXMLEventWriter(out);
XMLEvent event;
while ((level > 0) && reader.hasNext());
{
event = reader.nextEvent();
if (event.isStartElement())
{
level++;
}
else if (event.isEndElement())
{
level--;
}
writer.add(event);
}
writer.flush();
String element = new String(outStream.toByteArray());
ただし、呼び出し元のコードがLevel N-1
要素に到達したことを認識せず、次の要素に進む場合、上記は役に立ちません。Level N
<value>
SAX
ソリューションは理想的ですが、XSLT
テンプレートを介してファイルを前処理することさえ許容されます。
何か案は?