2011-02-03 28 views
6

Tôi có một hệ thống phân cấp các lớp được tạo bởi JAXB. Tôi muốn sắp xếp một lớp con như là một phần tử lớp cơ sở (nhưng với tất cả các thuộc tính lớp con), sử dụng xsi: type để chỉ ra kiểu cụ thể.JAXB Marshalling and Polymorphism

Ví dụ, với một động vật và một lớp con chim:

<xs:complexType name="animal" abstract="true"> 
    <xs:sequence> 
     <xs:element name="name" type="xs:string"/> 
    </xs:sequence> 
</xs:complexType> 

<xs:complexType name="bird"> 
    <xs:complexContent> 
     <xs:extension base="animal"> 
      <xs:sequence> 
       <xs:element name="maxAltitude" type="xs:int"/> 
      </xs:sequence> 
     </xs:extension> 
    </xs:complexContent> 
</xs:complexType> 

<xs:element name="Animal" type="animal"/> 
<xs:element name="Bird" type="bird"/> 

Không có vấn đề làm thế nào tôi sắp xếp một Bird, ví dụ:

Bird sparrow = new Bird(); 
sparrow.setName("Sparrow"); 
sparrow.setMaxAltitude(1000); 

JAXBContext context = JAXBContext.newInstance(Animal.class, Bird.class); 
Marshaller marshaller = context.createMarshaller(); 
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
marshaller.marshal(sparrow, System.out); 

Kết quả luôn luôn là một yếu tố Bird:

<Bird xmlns="http://mycompany.com/animals"> 
    <name>Sparrow</name> 
    <maxAltitude>1000</maxAltitude> 
</Bird> 

Tuy nhiên những gì tôi muốn là điều này (tất cả các thuộc tính của phân lớp, loại xsi, tên phần tử lớp cơ sở):

<Animal xmlns="http://mycompany.com/animals" 
     xsi:type="bird" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <name>Sparrow</name> 
    <maxAltitude>1000</maxAltitude> 
</Animal> 

Có gì kỳ lạ là nếu tôi tạo ra một yếu tố wrapper:

<xs:complexType name="animalWrapper"> 
    <xs:sequence> 
     <xs:element name="Animal" type="animal"/> 
    </xs:sequence> 
</xs:complexType> 

<xs:element name="AnimalWrapper" type="animalWrapper"/> 

và sắp xếp nó, nó sử dụng các loại lớp cơ sở:

<AnimalWrapper xmlns="http://mycompany.com/animals" 
    <Animal xsi:type="bird" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
     <name>Sparrow</name> 
     <maxAltitude>1000</maxAltitude> 
    </Animal> 
</AnimalWrapper> 

Nếu tôi tự xây dựng XML của tôi mong muốn tài liệu, JAXB không có vấn đề unmarshalling nó. Làm thế nào tôi có thể viết lược đồ XML của tôi và/hoặc cấu hình JAXB để cho phép hành vi marshalling mong muốn của tôi?

Cảm ơn.

Trả lời

1

Bạn có thể làm như sau:

QName qName = jc.createJAXBIntrospector().getElementName(new Animal()); 
JAXBElement<Animal> jaxbElement = new JAXBElement<Animal>(qName, Animal.class, new Bird()); 
marshaller.marshal(jaxbElement, System.out); 

Check-out:

+0

Cảm ơn. Ví dụ của bạn có một trình bao bọc xung quanh các mục có tính đa hình, như ví dụ AnimalWrapper của tôi và không phải là những gì tôi đang tìm kiếm. Tôi muốn đa hình ở phần tử gốc. – SingleShot

+0

Tôi đã cập nhật câu trả lời của mình để giải quyết trường hợp gốc. –

+0

Cảm ơn. Động vật là trừu tượng nên tôi không thể làm điều đó. Tôi có thể nới lỏng lược đồ mà tôi cho là, nhưng tôi không muốn. Tôi sẽ chơi xung quanh với những thứ tương tự như những gì bạn đề nghị. – SingleShot

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