2011-09-07 27 views
9

Tôi cố gắng để unmarshall XML sau đây sử dụng JAXB:Đối phó với JAXB Collections

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

Tôi đã tạo ra tất cả các lớp học sử dụng XJC. Nếu tôi muốn truy cập bộ sưu tập của Nhà soạn nhạc, tôi phải thực hiện việc này:

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

Có cách nào để tôi có thể thực hiện những việc sau thay thế không?

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

Tôi đánh giá cao nhu cầu đối tượng Composers khi nó xuất phát từ XML, nhưng khi giao dịch với Java, có POJO trung gian lưu trữ các bộ sưu tập có vẻ hơi dư thừa.

XSD của tôi là:

<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

Bạn có lược đồ mà bạn đã sử dụng để tạo POJO không? –

+0

Danh sách composers = work.getComposers(). GetComposer(); điều này có vẻ không đúng. Nó sẽ trả lại cho bạn chỉ một nhà soạn nhạc không phải là danh sách các nhà soạn nhạc. Trong khi đó, danh sách composers = work.getComposers(); điều này có vẻ chính xác. –

+0

Tôi đã thêm lược đồ XSD – seedhead

Trả lời

6

Plugin @XmlElementWrapper thực hiện chính xác những gì bạn muốn.

+1

Cảm ơn William! Rất tiếc, plugin này không hỗ trợ JAXB 2.1, chỉ 2.0. Là tùy chọn duy nhất ở đây để hạ cấp xuống 2.0? – seedhead

+0

Tôi đang sử dụng nó trong một dự án với JAXB 2.2.3 mà không có bất kỳ vấn đề gì. Bạn có thể cho tôi biết bạn đang gặp lỗi gì không? –

+0

Không có lỗi nhưng các lớp được tạo ra từ XJC không chứa các chú thích @XmlElementWrapper dự kiến. Tôi đang sử dụng Java 6 và JAXB 2.1, bạn có đang sử dụng Java 6 không? – seedhead

2

Đối với bất kỳ ai không thể hoặc không muốn sử dụng plugin: Nếu bạn có thể sống với cấu trúc XML khác, có thể tránh tạo các lớp trình bao bọc thêm bằng cách sử dụng maxoccurs="unbounded" và bỏ phần tử chứa. Sử dụng ví dụ ban đầu:

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

sẽ tạo ra một cấu trúc như thế này:

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

này sẽ đặt một phương pháp vào loại công việc mà trả về một đối tượng List<Composer>. Rất tiếc, phương pháp này được gọi là getComposer thay vì getComposers, nhưng bạn có thể sử dụng annotations or custom bindings để khắc phục sự cố đó.

Các vấn đề liên quan