2011-09-07 13 views
9

Staram się wycofać następujące XML przy użyciu JAXB:czynienia z JAXB Kolekcje

<Works> 
    <Work> 
     <Composers> 
      <Composer> 
       <Name>A name</Name> 
      </Composer> 
      <Composer> 
       <Name>A name 2</Name> 
      </Composer> 
     </Composers> 
    </Work> 
</Works> 

mam generowane wszystkich klas korzystających XJC. Jeśli chcę uzyskać dostęp do kolekcji Kompozytorów, muszę to zrobić:

List<Composer> composers = work.getComposers().getComposer(); 

Czy mogę zamiast tego wykonać następujące czynności?

List<Composer> composers = work.getComposers(); 

doceniam potrzebę obiektu kompozytorów, jak to wynika z XML, ale gdy mamy do czynienia w Javie, mające pośredni POJO który przechowuje zbiory wydaje się nieco zbędny.

Moje XSD jest:

<xsd:complexType name="Works"> 
    <xsd:sequence> 
     <xsd:element name="Work" type="Work" maxOccurs="unbounded" minOccurs="0"></xsd:element> 
    </xsd:sequence> 
</xsd:complexType> 

<xsd:complexType name="Work"> 
    <xsd:sequence> 
     <xsd:element name="Composers" type="Composers"></xsd:element> 
    </xsd:sequence> 
</xsd:complexType> 

<xsd:complexType name="Composers"> 
    <xsd:sequence> 
     <xsd:element name="Composer" type="Composer" maxOccurs="unbounded" minOccurs="0"></xsd:element> 
    </xsd:sequence> 
</xsd:complexType> 

<xsd:complexType name="Composer"> 
    <xsd:sequence> 
     <xsd:element name="Name" type="xsd:string"></xsd:element> 
    </xsd:sequence> 
</xsd:complexType> 

+0

Czy masz schemat, który został użyty do wygenerowania POJO? –

+0

Lista composers = work.getComposers(). GetComposer(); to nie wygląda dobrze. Powinien powrócić ci tylko jeden kompozytor, a nie lista kompozytorów. Natomiast lista composers = work.getComposers(); to wygląda na poprawne. –

+0

Dodałem mój schemat XSD – seedhead

Odpowiedz

6

Wtyczka @XmlElementWrapper robi dokładnie to, co chcesz.

+1

Dzięki William! Niestety ta wtyczka nie obsługuje JAXB 2.1, tylko 2.0. Czy jedyną opcją jest tutaj przejście na wersję 2.0? – seedhead

+0

Używam go w projekcie z JAXB 2.2.3 bez żadnych problemów. Czy możesz mi powiedzieć, jaki błąd widzisz? –

+0

Brak błędu, ale wygenerowane klasy z XJC nie zawierają oczekiwanych adnotacji @XmlElementWrapper. Używam Java 6 i JAXB 2.1, czy używasz także Java 6? – seedhead

2

Dla każdego, kto nie może lub nie chce korzystać z wtyczki: Jeśli możesz żyć z inną strukturą XML, możesz uniknąć generowania dodatkowych klas opakowania, po prostu używając maxoccurs="unbounded" i pomijając element zawierający. Korzystanie oryginalny przykład:

<xsd:element name="Work" type="Work" maxOccurs="unbounded" minOccurs="0"/> 

<xsd:complexType name="Work"> 
    <xsd:sequence> 
     <xsd:element name="Composer" type="Composer" maxOccurs="unbounded" minOccurs="0"/> 
    </xsd:sequence> 
</xsd:complexType> 

<xsd:complexType name="Composer"> 
    <xsd:sequence> 
     <xsd:element name="Name" type="xsd:string"></xsd:element> 
    </xsd:sequence> 
</xsd:complexType> 

będzie produkować struktury takiego:

<Work> 
    <Composer> 
     <Name>A name</Name> 
    </Composer> 
    <Composer> 
     <Name>A name 2</Name> 
    </Composer> 
</Work> 

ten wprowadzi metodę na rodzaj pracy, która zwraca List<Composer> obiekt. Niestety metoda nazywa się getComposer zamiast getComposers, ale można użyć annotations or custom bindings, aby rozwiązać ten problem.