Вопросы о формате вывода JAXB XML - PullRequest
12 голосов
/ 02 марта 2009

У меня есть классы Java со следующей структурой (имена классов ничего не подразумевают, я просто их составлял).

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

Проблема, с которой я столкнулся, связана с выводом XML, сгенерированным JAXB при сортировке экземпляра Test. Вывод 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, но все равно получаю неправильный отступ.

Спасибо.

Ответы [ 4 ]

9 голосов
/ 19 июля 2010

Отступ происходит по модулю 8, в

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

вы найдете

int i = depth%8;
2 голосов
/ 12 июля 2013

Одна из перегрузок метода marshal() маршалера принимает XMLStreamWriter, поэтому вы можете обойти механизм форматирования с поврежденным мозгом в эталонной реализации JAXB, написав свой собственный модуль записи потока XML-форматирования. В конечном итоге вы сделаете что-то вроде этого:

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 );
}
1 голос
/ 09 ноября 2009

Я не думаю, что есть предел. Я видел очень глубокое вложение без каких-либо трудностей. Есть ли у вас контроль пробелов на месте? Кроме того, вы не предоставили определение класса RateThreshold, который создает неожиданный вывод.

0 голосов
/ 20 июня 2013

Вам необходимо установить ширину линии - по умолчанию 72.

OutputFormat of = new OutputFormat ();

of.setLineWidth (1000);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...