2009-11-21 14 views
18

私が直面している問題は、オブジェクトの大きなリストを1つのXMLファイルにマーシャリングする方法です。そのため、大規模なリストを1つの手順でマーシャルすることはできません。私はこれらのオブジェクトをチャンクで返すメソッドを持っていますが、JAXBを使用してマーシャリングします。マーシャラーはこれらのオブジェクトがルート要素ではないという例外を返します。これは通常の場合、1つのステップで完全なドキュメントをマーシャリングする場合は問題ありませんが、JAXB_FRAGMENTプロパティをtrueに設定すると発生します。JAXB Marshallerを使用して大きなファイルをストリーミングする方法は?

これで必要なXML出力:

<rootElem> 
    <startDescription></startDescription> 
    <repeatingElem></repeatingElem> 
    <repeatingElem></repeatingElem>... 
</rootElem> 

だから私は彼がの終了タグを記述します前に、私は動的にマーシャラーにそれを養うためにrepeatingElementsの次のチャンクをロードし、リスナーのいくつかの種類を必要とすると仮定rootElement。しかし、それを行う方法?今まで私は小さなファイルをマーシャリングするためにJAXBを使用していましたが、JAXBのドキュメントではそのユースケースのヒントはあまりありません。

答えて

-8

私はJAXBをあまり知らないので、助けません。しかし、あなたが気にしないなら、私は示唆を持っています。

XMLを書くことは読み込みよりもはるかに簡単です。そのため、問題の解決策は、より低レベルのアプローチを使用することです。利用可能なXML用オープンソースライブラリの1つを使用して、独自のマーシャラーを作成してください。私はあなたが簡単にdom4jを使用して何をすることができると思います。

9

あなたが発見したように、クラスに@XmlRootElementアノテーションがない場合、そのクラスのインスタンスをマーシャラに渡すことはできません。しかし、これを回避するには簡単な方法があります - オブジェクトをJAXBElementにラップし、代わりにマーシャラーに渡してください。

JAXBElementは、やや不器用な獣ですが、それは、マーシャリングするオブジェクトの要素名と名前空間、通常は@XmlRootElement注釈に含まれる情報を含みます。あなたが名前と名前空間を持っている限り、POJOをラップするためにJAXBElementを構築し、それを整列化することができます。

POJOがXJCによって生成された場合は、クラスも生成されます。このクラスには、ファクトリメソッドJAXBElementが組み込まれています。

繰り返す内部要素にはまだJAXB_FRAGMENTプロパティを使用する必要があります。そうしないとJAXBは毎回XMLプロローグのようなものを生成しますが、これは不要です。

15

私はこれが古い質問であることを知っていますが、別の同様の質問の重複を検索しています。

@skaffmanが示唆しているように、JAXB_FRAGMENTを有効にし、オブジェクトをJAXBElementでラップしてマーシャリングする必要があります。繰り返し要素の個々のインスタンスを繰り返しマーシャリングします。基本的には、これはおおよそ次のようなものです:

public class StreamingMarshal<T> 
{ 
    private XMLStreamWriter xmlOut; 
    private Marshaller marshaller; 
    private final Class<T> type; 

    public StreamingMarshal(Class<T> type) throws JAXBException 
    { 
     this.type = type; 
     JAXBContext context = JAXBContext.newInstance(type); 
     Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 
    } 

    public void open(String filename) throws XMLStreamException, IOException 
    { 
     xmlOut = XMLOutputFactory.newFactory().createXMLStreamWriter(new FileOutputStream(filename)); 
     xmlOut.writeStartDocument(); 
     xmlOut.writeStartElement("rootElement"); 
    } 

    public void write(T t) throws JAXBException 
    { 
     JAXBElement<T> element = new JAXBElement<T>(QName.valueOf(type.getSimpleName()), type, t); 
     marshaller.marshal(element, xmlOut); 
    } 

    public void close() throws XMLStreamException 
    { 
     xmlOut.writeEndDocument(); 
     xmlOut.close(); 
    } 
} 
+0

コンストラクタにmarshallerを設定する必要があります。 this.marshaller = m; –

関連する問題