2009-03-02 18 views
12

Mam klasy Java o następującej strukturze (nazwy klas nie sugerują niczego, właśnie je tworzyłem).JAXB Format wyjściowy XML pytania

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

Problem, który mam z wyjściem XML generowanym przez JAXB podczas ustawiania instancji testu. Wyjście XML zawsze będzie wyglądać następująco:

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

Jak widać, niektóre elementy nie są prawidłowo wcięty (czyli najgłębsze elementy, liczyć i okres). Dlaczego? Czy jest coś złego w sposobie tworzenia kontekstu JAXB? Czy istnieje maksymalny limit liczby elementów, które mogą być wcięte rekursywnie przez JAXB? Jak mogę to naprawić? Zauważ, że ustawiłem JAXB_FORMATTED_OUTPUT na true, ale nadal otrzymuję niewłaściwe wcięcie.

Dzięki.

+0

Czy byłeś w stanie rozwiązać ten problem? Mam również ten sam problem w moim XML generowane przy użyciu JAXB. Proszę, czy możesz mi doradzić ? –

+0

@ shivam-shekhar, nie, problem nadal istnieje :(ale jest mniej ważny w porównaniu do innych rzeczy, więc zostawiliśmy go tam – His

Odpowiedz

9

Wcięcia występuje modulo 8, w

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

znaleźć

int i = depth%8; 
+1

Ten problem jest unikalny dla implementacji Metro JAXB (RI) .Inne implementacje JAXB takie jak jak MOXy nie udostępniają tego problemu: http://www.eclipse.org/eclipselink/moxy.php –

1

Nie sądzę, że istnieje ograniczenie. Widziałem bardzo głębokie gniazdowanie, bez żadnych trudności. Czy masz jakąkolwiek kontrolę w miejscu? Ponadto nie podano definicji klasy RateThreshold, która tworzy nieoczekiwane dane wyjściowe.

0

trzeba ustawić szerokość linii - domyślnie 72.

OutputFormat z = new OutputFormat();

of.setLineWidth (1000);

2

Jednym z przeciążenia metody Marshaler marshal() akceptuje XMLStreamWriter, więc można pominąć mechanizmy formatowania uszkodzonego mózgu w Referencyjnej implementacji JAXB, pisząc własny formatujący strumień XML. Skończyłoby się na zrobieniu czegoś takiego:

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