2009-03-02 76 views
12

我有以下結構的Java類(類名不暗示任何東西,我只是把它們組合起來)。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中也遇到同樣的問題。你能給些建議麼 ? – 2016-08-15 12:38:16

+0

@ shivam-shekhar,nope,問題仍然存在:(但與其他事物相比它不太重要,所以我們只把它留在那裏 – His 2016-08-16 07:23:36

回答

9

縮進發生模8,在

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

你找到

int i = depth%8; 
1

我不認爲這是有限制的。我看到很深的嵌套,沒有任何困難。你有任何空白控制?另外,您還沒有提供RateThreshold類的定義,它是創建意外輸出的定義。

0

您需要設置線寬 - 默認值是=新OUTPUTFORMAT的72

OUTPUTFORMAT();

of.setLineWidth(1000);

2

編組器的marshal()方法的重載之一接受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); 
}