2010-03-15 7 views
16

Używam JAXB i xjc do kompilowania mojego schematu XML do klas Java. Nie chcę ręcznie edytować tych wygenerowanych klas. Mam schematu XML tak:Jak generować adnotację XMLElementWrapper za pomocą xjc i niestandardowego powiązania

<xs:element name="root"> 
    <xs:complexType> 
    <xs:sequence> 
     <xs:element name="items"> 
     <xs:complexType> 
      <xs:sequence> 
      <xs:element ref="item" /> 
      </xs:sequence> 
     </xs:complexType> 
     </xs:element> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 

XJC generuje klasę Items który zawiera tylko listę Item obiektów. Czy jest szansa na pominięcie klasy Items i wyświetlenie listy obiektów Item bezpośrednio w klasie ?

Wiem, że można to zrobić za pomocą adnotacji @XMLElementWrapper, ale nie wiem, jak powiedzieć xjc, aby utworzyć takie.

Dzięki za wszelkie sugestie!

poważaniem, Markus

Odpowiedz

11

Bjarne Hansen opracowane plugin do XJC, który był w stanie się tym zająć. Niestety, link do pierwotnej implementacji jest już martwy. Istnieje jednak projekt Dmitry'ego Katsubo na github, oparty na oryginalnym kodzie Bjarne'a z dodatkowymi ulepszeniami.

https://github.com/dmak/jaxb-xew-plugin


(Tylko dla odniesienia: http://www.conspicio.dk/blog/bjarne/jaxb-xmlelementwrapper-plugin: oryginalny link, już nie żyje)

+0

Thomas, dziękuję. Ten link to pierwsza właściwa treść, którą widziałem na ten temat. – mahonya

+0

Próbowałem przez chwilę korzystać z tej wtyczki, ale bez skutku. Nie jestem pewien, czy jest to zgodne z xjc 2.2.4 (co właśnie mam w tej chwili). Ponadto nie mam jaxb-xjc.jar (xjc jest częścią narzędzi JDK7). Na koniec chcę wywołać xjc z wiersza poleceń, a każdy jest bardzo mamą, jak to zrobić ([Kohsuke Kawaguchi] (http://weblogs.java.net/blog/kohsuke/archive/2005/06/writing_a_plugi.html) mówi: "Możesz także zrobić to z linii poleceń, ale nie jest to zbyt piękne.") Dlaczego nie możemy po prostu mieć jaxb: adnotację, aby powiedzieć xjc, aby "pomijał" poziom, tj. po prostu wygenerował '@ XmlElementWrapper'? –

+0

Zauważ, że moja odpowiedź pochodzi sprzed dwóch lat - użyłem wtedy wtyczki i działało dobrze, ale może być już nieaktualne. – Thomas

8

Pierwszy pozwala zerwać schematu tak, że nie istnieją żadne wewnętrzne klasy generowane:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified"> 
    <xs:element name="root" type="Root" /> 

    <xs:complexType name="Root"> 
     <xs:sequence> 
      <xs:element name="items" type="Items" /> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="Items"> 
     <xs:sequence> 
      <xs:element name="item" type="xs:string" maxOccurs="unbounded" /> 
     </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

Będziesz nadal otrzymywać dodatkowe zajęcia, ale nie wszystkie w jednym pliku. Teraz chcesz dodać sekcję do swojej kompilacji, aby użyć jaxb-xew-plugin. Używam Maven, więc dla mnie to wygląda tak:

<plugin> 
    <groupId>org.jvnet.jaxb2.maven2</groupId> 
    <artifactId>maven-jaxb2-plugin</artifactId> 
    <version>0.8.2</version> 
    <executions> 
     <execution> 
      <goals> 
       <goal>generate</goal> 
      </goals> 
      <configuration> 
       <args> 
        <arg>-no-header</arg> 
        <arg>-Xxew</arg> 
        <arg>-Xxew:instantiate lazy</arg> 
        <arg>-Xxew:delete</arg> 
       </args> 
       <plugins> 
        <plugin> 
         <groupId>com.github.jaxb-xew-plugin</groupId> 
         <artifactId>jaxb-xew-plugin</artifactId> 
         <version>1.0</version> 
        </plugin> 
       </plugins> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

Jeśli zaczniesz używać nazw tak, że generowane klasy mają nazwy pakietów, opuść flagę -Xxew:delete, ponieważ nie jest to błąd, który niedawno ustalone, gdzie było usunięcie obiekty nie powinny. Alternatywnie możesz pobrać kod z github i użyć go jako 1.1-SNAPSHOT.

Kiedy robię, że mam kod generowany że myślę szukasz:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Root", propOrder = { 
    "items" 
}) 
public class Root { 

    @XmlElementWrapper(name = "items", required = true) 
    @XmlElement(name = "item") 
    protected List<String> items; 

    public List<String> getItems() { 
     if (items == null) { 
      items = new ArrayList<String>(); 
     } 
     return items; 
    } 

    public void setItems(List<String> items) { 
     this.items = items; 
    } 

} 
Powiązane problemy