2009-03-02 19 views
12

私は次の構造のクラスを持っています(クラス名には何の意味もありません)。JAXB XML出力形式の質問

package test; 

import java.util.ArrayList; 
import java.util.List; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlElementWrapper; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlValue; 

@XmlRootElement 
public class Test 
{ 
    @XmlAccessorType(XmlAccessType.FIELD) 
    static class Machine 
    { 
     @XmlElementWrapper(name="servers") 
     @XmlElement(name="server") 
     List<Server> servers = new ArrayList<Server>(); 
    } 

    @XmlAccessorType(XmlAccessType.FIELD) 
    static class Server 
    { 
     Threshold t = new Threshold(); 
    } 

    @XmlAccessorType(XmlAccessType.FIELD) 
    static class Threshold 
    { 
     RateThreshold load = new RateThreshold(); 
    } 

    @XmlAccessorType(XmlAccessType.FIELD) 
    static class RateThreshold 
    { 
     @XmlAccessorType(XmlAccessType.FIELD) 
     static class Rate 
     { 
      int count; 
      Period period = new Period(); 
     } 

     @XmlAccessorType(XmlAccessType.FIELD) 
     private static class Period 
     { 
      @XmlAttribute 
      private String type = "second"; 

      @XmlValue 
      private float period; 
     } 

     Rate min = new Rate(); 
     Rate max = new Rate(); 
    } 

    @XmlElementWrapper(name="machines") 
    @XmlElement(name="machine") 
    List<Machine> machines = new ArrayList<Machine>(); 

    public static void main(String[] args) 
    { 
     Machine m = new Machine(); 
     Server s = new Server(); 
     s.t.load.max.count = 10; 
     s.t.load.min.count = 1; 
     m.servers.add(s); 

     Test t = new Test(); 
     t.machines.add(m); 

     JAXBContext jaxbContext; 
     Marshaller marshaller; 
     try 
     { 
      jaxbContext = JAXBContext.newInstance(Test.class); 
      marshaller = jaxbContext.createMarshaller(); 
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
      marshaller.marshal(t, System.out); 
     } 
     catch (JAXBException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

私が抱えている問題は、テストインスタンスをマーシャリングするときにJAXBによって生成されたXML出力です。 XML出力は常に次のようになります。あなたが見ることができるように、いくつかの要素が適切にインデントされていない

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<test> 
    <machines> 
     <machine> 
      <servers> 
       <server> 
        <t> 
         <load> 
          <min> 
<count>1</count> 
<period type="second">0.0</period> 
          </min> 
          <max> 
<count>10</count> 
<period type="second">0.0</period> 
          </max> 
         </load> 
        </t> 
       </server> 
      </servers> 
     </machine> 
    </machines> 
</test> 

(つまり、最も深い要素は、カウント期間)。何故ですか? JAXBのコンテキストを作成する方法に何か問題がありますか?あるいは、JAXBが再帰的にインデントできる要素の数に上限がありますか?どうすればこの問題を解決できますか?私もJAXB_FORMATTED_OUTPUTをtrueに設定しましたが、依然として不適切なインデントを取得しています。

ありがとうございました。

+0

これを解決できましたか? JAXBを使用して生成されたXMLでも同じ問題が発生しています。あなたがアドバイスしていただけますか ? –

+0

@ shivam-shekhar、いいえ、問題はまだそこにあります:しかし、それは他のものと比較してそれほど重要ではないので、そこに残しました – His

答えて

9

インデントは

com.sun.xml.bind.v2.runtime.output.IndentingUTF8XmlOutput 

にあなたは線幅を設定する必要が

int i = depth%8; 
+1

この問題は、JAXB(RI)のMetro実装に固有です。 MOXyはその問題を共有していないため、http://www.eclipse.org/eclipselink/moxy.php –

1

制限はありません。私は非常に深い入れ子を見ましたが、何の問題もありませんでした。空白のコントロールがありますか?また、予期しない出力を生成するRateThresholdクラスの定義も提供していません。

0

を見つけ、モジュロ8を発生する - デフォルト)=新OUTPUTFORMAT(の72

OUTPUTFORMATです。 .setLineWidth(1000);

2

マーシャラのmarshal()メソッドのオーバーロードの1つは、XMLStreamWriterを受け入れるため、独自の書式設定XMLストリームライターを記述することによって、JAXBのリファレンス実装の脳損傷型フォーマットメカニズムを回避できます。あなたは次のようなことをするでしょう:

public static void SaveContainer(Container container, OutputStream stream) throws ... 
{ 
    XMLOutputFactory factory = XMLOutputFactory.newInstance(); 
    XMLStreamWriter writer = factory.createXMLStreamWriter(stream, "UTF-8"); 
    writer = new MyAwesomeCoolFormattingXMLStreamWriter(writer); 
    marshaller.marshal(container, writer); 
}