java - parse - Preguntas de formato de salida JAXB XML
object to xml java spring (4)
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.
Tengo clases de Java con la siguiente estructura (los nombres de clase no implican nada, solo los estaba inventando).
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 así:
<?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 puede ver, algunos elementos no se sangran correctamente (es decir, los elementos más profundos, el recuento y el 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.
La sangría ocurre modulo 8, en
com.sun.xml.bind.v2.runtime.output.IndentingUTF8XmlOutput
tu encuentras
int i = depth%8;
Necesita establecer el ancho de línea; el valor predeterminado es 72.
OutputFormat de = new OutputFormat ();
of.setLineWidth (1000);
Una de las sobrecargas del método marshal()
del Marshaller 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 al escribir su propio formato de secuenciador XML. Terminarías 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 );
}