Pregunta

Tengo clases de Java con la siguiente estructura (los nombres de las clases no implican nada, solo las 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 calcular 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 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 JAXB? ¿O hay un límite máximo de cuántos elementos pueden ser sangrados recursivamente por JAXB? ¿Cómo podría arreglar esto? Tenga en cuenta que también he establecido JAXB_FORMATTED_OUTPUT en true, pero aún así tengo la sangría incorrecta.

Gracias.

¿Fue útil?

Solución

La sangría ocurre módulo 8, en

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

lo encuentras

int i = depth%8;

Otros consejos

Una de las sobrecargas del método marshal () del contador de referencias acepta un XMLStreamWriter, por lo que puede omitir el mecanismo de formato dañado por el cerebro de la Implementación de Referencia de JAXB escribiendo su propio flujo XML de formato. escritor. 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 );
}

No creo que haya un límite. He visto nidos muy profundos, sin ninguna dificultad. ¿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.

Debes establecer el ancho de línea, el valor predeterminado es 72.

OutputFormat of = new OutputFormat ();

of.setLineWidth (1000);

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top