2010-09-07 43 views
16

Có một câu trả lời giữ chỗ trên tại the unofficial guide với một liên kết đến một bài viết mà (với tôi) có vẻ khá không liên quan.Tại sao JAXB đôi khi ánh xạ tới JAXBElement?

Tôi sử dụng XJC để tạo các lớp JAXB của mình và trong khi hầu hết trong số chúng ánh xạ với nhau như mong đợi, một số yếu tố được ánh xạ tới JAXBElement<Foo>. Điều này gây khó chịu nhất cho đồ thị có chu kỳ, trong đó đôi khi nút cha của phần tử Foo sẽ là JAXBElement<Foo>, không có thuộc tính gốc, phá vỡ chu trình.

Tôi có thể nghĩ nhiều cách giải quyết khác nhau, nhưng sẽ đẹp hơn nếu ai đó có thể giải thích hành vi này với tôi. Tại sao JAXB đôi khi ánh xạ một phần tử <Foo> tới JAXBElement<Foo> thay vì Foo?

+0

Xem http://stackoverflow.com/questions/3639313/xsd-formatting-elementcomplextype-vs-complextype-element/3639375#3639375 để được giải thích – skaffman

+0

@skaffman: Eh? Tôi không thấy câu trả lời của bạn liên quan đến việc liệu xjc có chọn 'JAXBElement ' trên 'Foo' hay không. –

+1

@Chris: Bởi vì nó được xác định một phần bởi sự lựa chọn của các loại vô danh hoặc các loại tên trong lược đồ nguồn. – skaffman

Trả lời

10

JAXBElement được sử dụng để bảo toàn tên phần tử/không gian tên trong các trường hợp sử dụng khi không có đủ thông tin trong mô hình đối tượng. Sự xuất hiện phổ biến nhất là với các nhóm thay thế:

Với Thay Nhóm:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org" 
    xmlns="http://www.example.org" 
    elementFormDefault="qualified"> 

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

    <xs:element name="anElement" type="xs:string"/> 

    <xs:element name="aSubstituteElement" type="xs:string" substitutionGroup="anElement"/> 

</xs:schema> 

sẽ generate:

package org.example; 

import javax.xml.bind.JAXBElement; 
import javax.xml.bind.annotation.*; 

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

    @XmlElementRef(name = "anElement", namespace = "http://www.example.org", type = JAXBElement.class) 
    protected JAXBElement<String> anElement; 

    public JAXBElement<String> getAnElement() { 
     return anElement; 
    } 

    public void setAnElement(JAXBElement<String> value) { 
     this.anElement = ((JAXBElement<String>) value); 
    } 

} 

Without Thay Nhóm:

Nếu bạn loại bỏ nhóm thay thế:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org" 
    xmlns="http://www.example.org" 
    elementFormDefault="qualified"> 

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

    <xs:element name="anElement" type="xs:string"/> 

</xs:schema> 

Lớp sau đây sẽ được tạo ra:

package org.example; 

import javax.xml.bind.annotation.*; 

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

    @XmlElement(required = true) 
    protected String anElement; 

    public String getAnElement() { 
     return anElement; 
    } 

    public void setAnElement(String value) { 
     this.anElement = value; 
    } 

} 

Bạn cũng có thể có được một JAXBElement khi bạn unmarshal, so sánh các ví dụ sau:

+0

Cảm ơn, các nhóm thay thế thực sự là nơi điều này đang xảy ra. Vậy là nó là một lỗi trong 'afterUnmarshal (Unmarshaller u, Object parent) ', những lớp này có thể thay thế được chuyển JAXBElement của riêng chúng thành' parent' của chúng? Đặc biệt vì dường như không có cách nào để lấy yếu tố cha mẹ thực sự từ JAXBElement. –

+0

Điều này dường như là một lỗi trong Metro JAXB (việc triển khai tham chiếu, được bao gồm trong Java SE 6). Trong thực thi JAXB MOXy (http://www.eclipse.org/eclipselink/moxy.php) đối tượng cha mẹ chính xác được chuyển tới phương thức afterUnmarshal. –

0

Để tránh ánh xạ tới JAXBElement? Tôi đã làm những việc này nó phù hợp với tôi:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
      xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
      jaxb:extensionBindingPrefixes="xjc" 
      jaxb:version="2.0"> 

    <xs:annotation> 
     <xs:appinfo> 
      <jaxb:globalBindings generateValueClass="false"> 
      <xjc:simple /> 
      </jaxb:globalBindings> 
     </xs:appinfo> 
    </xs:annotation> 

</xs:schema> 

Lưu tệp này vào tệp xml và cung cấp dưới dạng tệp ràng buộc.

Reference Link

Tạo lớp JAXB sử dụng eclipse không quên để cung cấp cho các file liên kết tạo ra với xml trên và kiểm tra "Cho phép mở rộng bán hàng" như sau:

enter image description here

Với những thay đổi i am có thể Get loại bỏ JAXBElement trong các lớp được tạo ra xjc để chuyển đổi xsd thành các lớp được tạo ra JAXB.

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