XMLバインディングが非常に好まれるように、いくつかのXSDファイルで既にスキーマが提供されている可能性のある大きなXMLファイルを解析する必要があります。 JAXBを使ってファイルを解析することができるかどうか、もしあれば、どのようにすればいいのかを知りたい。JAXBは大きなXMLファイルをチャンクで解析できますか
答えて
これは、user guideで詳細に説明されています。 http://jaxb.java.net/からのJAXBダウンロードには、一度に1つのチャンクを解析する方法の例が含まれています。
文書が大きい場合には、その中に繰り返し 部分がありますので、それは通常 です。大量の広告申込情報のリスト をご購入の場合は、 か、おそらく ログエントリが多いXMLログファイルです。
この種類のXMLは、チャンク処理のためには、 に適しています。主なアイデアは、 StAX APIを使用してループを実行し、 個々のチャンクを非マーシャルにすることです 。あなたのプログラムは の単一のチャンクで動作し、それからそれを投げ捨てます。 この方法では、 のメモリに1つのチャンクしか保存されないため、 は大きなドキュメントを処理できます。
はこれを行う方法の詳細についてJAXB RI分布 でストリーミングアンマーシャル 例と部分-アンマーシャル 例を参照してください。 「 ストリーミングアンマーシャリングの例では、それが 任意のネストレベルでチャンクを扱うことができる という利点があり、まだあなたはプッシュモデルに対処する それは--- JAXBのアンマーシャラーは、あなたとあなたに新しい チャンクを「プッシュ」しますが必要です する必要があります。対照的に
、部分アンマーシャリング 例は、(通常容易処理を行った )プルモデルで動作し、 このアプローチは 繰り返し部分以外のデータバインディング部のいくつかの制限 を有しています。
コードが重要なので、大きなファイルをチャンクに読み込むのはPartialUnmarshaller
です。これは、イヴ・Amsellemの答えはかなり良いですが、すべての要素がまったく同じ型である場合にのみ動作する方法new PartialUnmarshaller<YourClass>(stream, YourClass.class)
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.*;
import java.io.InputStream;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static javax.xml.stream.XMLStreamConstants.*;
public class PartialUnmarshaller<T> {
XMLStreamReader reader;
Class<T> clazz;
Unmarshaller unmarshaller;
public PartialUnmarshaller(InputStream stream, Class<T> clazz) throws XMLStreamException, FactoryConfigurationError, JAXBException {
this.clazz = clazz;
this.unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
this.reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);
/* ignore headers */
skipElements(START_DOCUMENT, DTD);
/* ignore root element */
reader.nextTag();
/* if there's no tag, ignore root element's end */
skipElements(END_ELEMENT);
}
public T next() throws XMLStreamException, JAXBException {
if (!hasNext())
throw new NoSuchElementException();
T value = unmarshaller.unmarshal(reader, clazz).getValue();
skipElements(CHARACTERS, END_ELEMENT);
return value;
}
public boolean hasNext() throws XMLStreamException {
return reader.hasNext();
}
public void close() throws XMLStreamException {
reader.close();
}
void skipElements(int... elements) throws XMLStreamException {
int eventType = reader.getEventType();
List<Integer> types = asList(elements);
while (types.contains(eventType))
eventType = reader.next();
}
}
これを動作させるには、XMLStreamConstants.START_DOCUMENTなどを使用する必要があります。 –
@MatthiasWuttke静的インポートとして追加できます。 import static javax.xml.stream.XMLStreamConstants。*; –
また、GuavaのInts.asListまたはjava8のIntStream.of(要素).boxed()。collect(Collectors.toList());が必要な場合があります。 –
使用することができます。そうしないと、unmarshallは例外をスローしますが、読者はすでにバイトを消費しているため、回復できません。代わりに、Skaffmanのアドバイスに従って、JAXB jarのサンプルを見てください。
それがどのように動作するかを説明するには、次の
- は、JAXBのアンマーシャラーを作成します。
- 適切な要素を傍受するために、アンマーシャラーにリスナーを追加します。これは、整列されていない要素がメモリに格納されていないことを確実にするために、ArrayListを「ハッキングする」ことによって行われます。
- SAXパーサーを作成します。これがストリーミングが起こる場所です。
- アンマーシャラーを使用して、SAXパーサーのハンドラーを生成します。
- ストリーム!
解決策を汎用*に変更しました。しかし、それはいくつかの反映が必要でした。これがOKでない場合は、JAXB jarのコードサンプルを見てください。
ArrayListAddInterceptor.java
import java.lang.reflect.Field;
import java.util.ArrayList;
public class ArrayListAddInterceptor<T> extends ArrayList<T> {
private static final long serialVersionUID = 1L;
private AddInterceptor<T> interceptor;
public ArrayListAddInterceptor(AddInterceptor<T> interceptor) {
this.interceptor = interceptor;
}
@Override
public boolean add(T t) {
interceptor.intercept(t);
return false;
}
public static interface AddInterceptor<T> {
public void intercept(T t);
}
public static void apply(AddInterceptor<?> interceptor, Object o, String property) {
try {
Field field = o.getClass().getDeclaredField(property);
field.setAccessible(true);
field.set(o, new ArrayListAddInterceptor(interceptor));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Main.java
public class Main {
public void parsePurchaseOrders(AddInterceptor<PurchaseOrder> interceptor, List<File> files) {
try {
// create JAXBContext for the primer.xsd
JAXBContext context = JAXBContext.newInstance("primer");
Unmarshaller unmarshaller = context.createUnmarshaller();
// install the callback on all PurchaseOrders instances
unmarshaller.setListener(new Unmarshaller.Listener() {
public void beforeUnmarshal(Object target, Object parent) {
if (target instanceof PurchaseOrders) {
ArrayListAddInterceptor.apply(interceptor, target, "purchaseOrder");
}
}
});
// create a new XML parser
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
XMLReader reader = factory.newSAXParser().getXMLReader();
reader.setContentHandler(unmarshaller.getUnmarshallerHandler());
for (File file : files) {
reader.parse(new InputSource(new FileInputStream(file)));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
*このコードはテストされ、説明のみを目的としておりされていません。
- 1. Javaで大きなXMLファイルを解析する
- 2. 非常に大きなXMLファイルをPHPで解析する
- 3. Androidで大きなxmlファイルを解析する際の問題
- 4. JAXBでXml解析問題
- 5. 単一の解析で大きなファイルを解析する
- 6. 大きなファイルをANTLRで解析することはできますか?
- 7. 大きなJSONファイルを解析する
- 8. チャンクでXMLファイルを解析する方法
- 9. PL/SQLで大きなXML(> 4k)を解析する
- 10. node.jsで大きなxml 500Mを解析する
- 11. Javaスクリプトでxml DOM(ファイルから)を解析できません
- 12. 大きなXMLファイルを解析する必要があります。ベストプラクティス?
- 13. 大きなJSONファイルをJSONで解析する(OutOfMemoryError)
- 14. Pythonで大規模な疑似XMLファイルを解析する
- 15. XmlSlurperで大規模なXMLファイルを解析する
- 16. 大きなファイル(100GB)チャンクでメモリマッピングを使用してチャンクで読む
- 17. xmlデータを解析できません
- 18. javascriptでローカルXMLファイルを解析できません
- 19. 大きな複合XMLを解析する方法
- 20. Javaを使用して大きなXMLファイルを解析するにはどうすればよいですか?
- 21. Androidで大きなXMLファイルを扱う
- 22. 大きなファイルからマルチプロセッシングのデータをチャンクする?
- 23. Pythonでスレッディングを利用して大きなファイルを解析するには?
- 24. xmlをtouch xmlで解析できません
- 25. なぜ私はjavascriptでxmlを解析できないのですか?
- 26. 非常に大きなXMLファイルの解析とJavaオブジェクトへのマーシャリング
- 27. C#で非常に巨大なXMLファイルを解析するには?
- 28. eclipseで大きなXMLファイルを表示していますか?
- 29. ANTLR4大きなファイルを解析するPython
- 30. 非常に大きなファイルを解析するPython json
これは私がこれを調べて見つけたサイトの1つですが、セクション4.4.1で言及した「ストリーミングアンマーシャリング」と「部分アンマーシャリング」の例は見つかりませんでした。 –
奇数。あなたはどこを探していますか? jaxb.dev.java.net/2.1.12からJARをダウンロードして解凍しました。「samples」の下に「partial-unmarshalling」と「stream-unmarshalling」があります。 – skaffman