2009-03-02 74 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); 
}