2009-03-02 15 views
12

Tengo clases de Java con la siguiente estructura (los nombres de clase no implican nada, solo los estaba inventando).JAXB XML formato de salida de preguntas

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(); 
     } 
    } 
} 

El problema que tengo es con la salida XML generada por JAXB al coordinar una instancia de prueba. La salida XML siempre se vería como la siguiente:

<?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> 

Como se puede ver, algunos elementos no están siendo adecuadamente sangría (es decir, los elementos más profundos, cuentan y período). ¿Porqué es eso? ¿Hay algún problema con la forma en que creé el contexto de JAXB? ¿O hay un límite máximo para la cantidad de elementos que JAXB puede sancionar recursivamente? ¿Cómo podría arreglar esto? Tenga en cuenta que también he configurado JAXB_FORMATTED_OUTPUT en verdadero, pero aún así obtengo la indentación incorrecta.

Gracias.

+0

¿Pudo resolver esto? También estoy teniendo el mismo problema en mi XML generado usando JAXB. Puede aconsejarme ? –

+0

@ shivam-shekhar, no, el problema sigue ahí :(pero es menos importante en comparación con otras cosas, así que lo dejamos allí – His

Respuesta

9

sangría ocurre módulo 8, en

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

a encontrar

int i = depth%8; 
+1

Ese problema es exclusivo de la implementación de JAXB (RI) en Metro. Otras implementaciones de JAXB tales como MOXy no comparten ese problema: http://www.eclipse.org/eclipselink/moxy.php –

1

No creo que haya un límite. He visto una anidación muy profunda, sin dificultades. ¿Tiene algún control de espacio en blanco en su lugar? Además, no ha proporcionado la definición de la clase RateThreshold, que es la que crea el resultado inesperado.

0

Es necesario configurar el ancho de línea - por defecto es 72.

OutputFormat de OutputFormat = new();

of.setLineWidth (1000);

2

Una de las sobrecargas del método marshal() del Marshaler acepta un XMLStreamWriter, por lo que puede eludir el mecanismo de formateo dañado por el cerebro de la Implementación de Referencia de JAXB escribiendo su propio formato de secuenciador XML. Usted terminaría haciendo algo como esto:

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); 
}