2009-03-02 3 views
12

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

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, но все равно получаю неправильный отступ.

Спасибо.

+0

Вы смогли это решить? У меня также есть такая же проблема в моем XML, сгенерированном с использованием JAXB. Вы могли бы посоветовать ? –

+0

@ shivam-shekhar, nope, проблема все еще существует: (но она менее важна по сравнению с другими вещами, поэтому мы просто оставили ее там – His

ответ

9

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

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

вы найдете

int i = depth%8; 
+1

Эта проблема уникальна для реализации Metro JAXB (RI). Другие реализации JAXB такие поскольку MOXy не разделяет эту проблему: http://www.eclipse.org/eclipselink/moxy.php –

1

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

0

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

OUTPUTFORMAT из = новый OUTPUTFORMAT();

of.setLineWidth (1000);

2

Одна из перегрузок метода маркер-маркера 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); 
}