2011-12-02 25 views
6

Tôi đang làm việc trên dự án Scala và chúng tôi muốn sử dụng XML để khởi tạo các đối tượng của mình bằng JAXB (không phải Spring). Tôi có một hệ thống phân cấp nơi các thành viên dữ liệu được thêm vào trong các lớp con. Một ví dụ đơn giản sẽ giống như thế này:JAXB có thể khởi tạo các giá trị trong các lớp cơ sở không?

class Animal 
{ 
    string name 
} 

class Cat extends Animal 
{ 
    int numLives 
} 

class Dog extends Animal 
{ 
    bool hasSpots 
} 

Tôi muốn để có thể khởi tạo một danh sách các loài động vật từ một khối XML mà trông giống như sau:

<Animals> 
    <Cat> 
     <name>Garfield</name> 
     <numLives>9</numLives> 
    </Cat> 
    <Dog> 
     <name>Odie</name> 
     <hasSpots>false</hasSpots> 
    </Dog> 
</Animals> 

Làm thế nào sẽ chúng tôi thiết lập các chú thích trong các lớp để có thể xử lý điều này?

Trả lời

0

Trong trường hợp này, tôi thích tạo một lược đồ XSD và tạo mã từ nó, vì vậy bạn đang ở bên an toàn. Nhưng để trả lời câu hỏi của bạn, có, bạn có thể. Các chú thích là XMLElement, XMLAttribute, XMLRootElement.

3

Ví dụ này, bạn sẽ muốn sử dụng các chú thích @XmlElementRef@XmlRootElement. Điều này tương ứng với khái niệm lược đồ XML của các nhóm thay thế. Điều này sẽ cho phép bạn có một danh sách các đối tượng từ một hệ thống phân cấp thừa kế được phân biệt bởi phần tử.

vật

này sẽ đóng vai trò là đối tượng gốc cho các mô hình miền. Nó có thuộc tính List được chú thích với @XmlElementRef. Điều này có nghĩa là nó sẽ khớp với các giá trị dựa trên giá trị của các chú thích @XmlRootElement của chúng.

package forum8356849; 

import java.util.List; 

import javax.xml.bind.annotation.*; 

@XmlRootElement(name="Animals") 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Cat.class, Dog.class}) 
public class Animals { 

    @XmlElementRef 
    private List<Animal> animals; 
} 

Animal

package forum8356849; 

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
class Animal 
{ 
    String name; 
} 

Cát

Chúng tôi sẽ chú thích các lớp Cat với chú thích @XmlRootElement. Điều này được sử dụng song song với chú thích @XmlElementRef trên Animals.

package forum8356849; 

import javax.xml.bind.annotation.*; 

@XmlRootElement(name="Cat") 
class Cat extends Animal 
{ 
    int numLives; 
} 

Chó

Chúng tôi cũng sẽ thêm một chú thích @XmlRootElement đến lớp Dog.

package forum8356849; 

import javax.xml.bind.annotation.*; 

@XmlRootElement(name="Dog") 
class Dog extends Animal 
{ 
    boolean hasSpots; 
} 

Demo

Bạn có thể sử dụng lớp sau đây để thấy rằng mọi thứ hoạt động như mong đợi. input.xml tương ứng với XML được cung cấp trong câu hỏi của bạn.

package forum8356849; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Animals.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum8356849/input.xml"); 
     Animals animals = (Animals) unmarshaller.unmarshal(xml); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(animals, System.out); 
    } 

} 

Để biết thêm Inforation

+1

Cảm ơn! Tôi sẽ cho nó một viên đạn! – fbl

+0

Ahh, tôi gặp phải một chút ...Ứng dụng của tôi cần hỗ trợ các plugin, '@XmlSeeAlso ({Cat.class, Dog.class})' ngụ ý rằng tôi cần biết về những người quyết định của tôi trong thời gian biên dịch. Bất kỳ cách nào xung quanh đó? – fbl

+0

@fbl - Bạn không cần phải sử dụng XmlSeeAlso nhưng JAXBContext không cần phải biết về các lớp con. Bạn có thể tìm thấy cách tiếp cận sau phù hợp hơn: http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html –

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