2012-02-15 34 views
7

Marshaller.JAXB_FRAGMENTプロパティを使用してマーシャリングするのに問題があります。ここに出力しようとしているXMLの単純なバージョンです。JAXB断片化マーシャリング

<Import> 
    <WorkSets> 
     <WorkSet> 
      <Work> 
      <Work> 
      ... 
      .. 
      ... 
     </WorkSet> 
     <WorkSet> 
      <Work> 
      <Work> 
      ... 
     </WorkSet> 
    <WorkSets> 
<Import> 
<Import>

<WorkSets>要素は、本質的に<WorkSet> & <Work>多数の要素を囲むだけコンテナ要素です。私は現在、<WorkSet>でマーシャルをしようとしています。

  1. それは最初<Import><WorkSets>要素をマーシャリングして、その後からマーシャルに<WorkSet>要素で、出力は<Import><WorkSets>タグで囲んで持つことは可能ですか?
  2. WorkSetレベルでマーシャリングするときに、xmlns='http://namespace.com'属性がWorkSetタグに関連付けられていますが、名前空間属性がWorksetに関連付けられていない状態でマーシャリングする方法はありますか?
+0

わかりません。 "と要素"とは何ですか?ワークセット、ワークセット、およびインポートのみが表示されます。 "...最初にマーシャルと要素をマーシャル、その後マーシャルを要素にして..."と言うとき、あなたはどういう意味ですか? – AlexR

+0

@AlexR質問を最初に投稿したとき、質問にタグを表示していなかったので、編集したので、今すぐ表示する必要があります。 – TyC

+0

この投稿で回答を受け入れた場合、[JAXB Fragment Marshal w/o namespace](http://stackoverflow.com/questions/9297872)という質問をなぜ複写したのですか?少なくとも質問は二股に分かれていると言います... –

答えて

17

基本的には、コンテナオブジェクトで完全なオブジェクトツリーを構築するのではなく、JAXBを使用してマーシャリングするためにWorkSetインスタンスのコレクションをストリーミングできるようにする必要があります。

XMLStreamWriterを使用して、WorkSetオブジェクトをJAXBElementでラップしてマーシャリングする方法があります。私はここに書き込みトラック上にあなたを置くべきラフコードスニペットだ、手元にあるサンプルコードをテストしていません。

FileOutputStream fos = new FileOutputStream("foo.xml"); 
XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(fos); 

writer.writeStartDocument(); 
writer.writeStartElement("Import"); 
writer.writeStartElement("WorkSets"); 

JAXBContext context = JAXBContext.newInstance(WorkSet.class); 
Marshaller m = context.createMarshaller(); 
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 
for (WorkSet instance : instances) 
{ 
    JAXBElement<WorkSet> element = new JAXBElement<WorkSet>(QName.valueOf("WorkSet"), WorkSet.class, instance); 
    m.marshal(element, writer); 
} 

writer.writeEndDocument(); // this will close any open tags 
writer.close(); 

注:上記は完全にテストされていないとで何かをめちゃくちゃにすることができますワークセットの各インスタンスを書き込むためのラッピングパーツWorkshopのインスタンスには、@XmlRootElementというアノテートされていないため、JAXBはオブジェクトのマーシャリングを拒否するため、ラップする必要があります。

+0

Thanks @JörnHorstmann、私はフラグメントの部分について忘れてしまい、ちょうど自分でそれを追加するために戻ってきました。 – Ophidian

+1

ありがとう!私はちょうどこれを試してみました、それはうまくいくようです。ワークセットインスタンスが整列されているときに何らかの理由でxmlns属性が各WorkSet要素にアタッチされているときに、マーシャルされているときにこのアトリビュートを割り当てられないようにする方法がありますか? – TyC

+0

それは、私は完全に確信していません。密接に私は推測JAXBのjavadocsを読んで始めたいと思います。ごめんなさい! – Ophidian

0

ルート要素を作成するために必要な要素で入力XMLをラップするだけの方法もあります。次に、ルート要素のJavaオブジェクトを取得し、探しているフラグメントのゲッターを呼び出します。例えば

、あなたはこのようなXMLを持っていた場合:

<XmlRootElement> 
    <FragmentElement> 
     <foo>This is the foo value</foo> 
     <bar>This is the bar value</bar> 
    </FragmentElement> 
</XmlRootElement> 

そして、あなたがこの手渡されました。

<FragmentElement> 
    <foo>This is the foo value</foo> 
    <bar>This is the bar value</bar> 
</FragmentElement> 

をあなたがXmlRootElementが含まタグで文字列をラップし、その後に結果の文字列を解析することができルートオブジェクトを取得し、そこからフラグメントオブジェクトを取得します。次のようなもの:

public FragementElement getFragmentElement(String xml) { 
    xml = "<XmlRootElement>" + xml + "</XmlRootElement>"; 
    ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes()); 
    JAXBElement obj = (JAXBElement) unmarshaller.unmarshal(is); 
    XmlRootElement xmlRootElement = (XmlRootElement) obj.getValue(); 
    FragementElement fragmentElement = xmlRootElement.getText(); 
    return fragmentElement; 
}