2011-12-02 55 views
6

我正在开发一个Scala项目,我们想用XML来初始化JAXB(不是Spring)对象。我有一个层次结构,更多的数据成员被添加到子类中。一个简单的例子会是这个样子:JAXB可以初始化基类中的值吗?

class Animal 
{ 
    string name 
} 

class Cat extends Animal 
{ 
    int numLives 
} 

class Dog extends Animal 
{ 
    bool hasSpots 
} 

我希望能够从一个XML块,看起来像这样初始化动物名单:

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

如何将我们设置类中的注释能够处理这个问题?

回答

0

在这种情况下,我更喜欢创建一个XSD模式并从中生成代码,因此您的安全性较高。 但是要回答你的问题,是的,你可以。注释是XMLElement,XMLAttribute,XMLRootElement。

3

对于此示例,您将要使用@XmlElementRef@XmlRootElement注释。这对应于替代组的XML模式概念。这将允许您获得继承层次结构中由元素区分的对象列表。

动物

这将作为根对象为域模型。它有一个List财产注释与@XmlElementRef。这意味着它将根据其@XmlRootElement注释的值匹配值。

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

动物

package forum8356849; 

import javax.xml.bind.annotation.*; 

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

我们将注释Cat类的@XmlRootElement注解。这与Animals上的@XmlElementRef注释串联使用。

package forum8356849; 

import javax.xml.bind.annotation.*; 

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

我们也将增加一个@XmlRootElement注释到Dog类。

package forum8356849; 

import javax.xml.bind.annotation.*; 

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

演示

您可以使用下面的类地看到,一切正常。 input.xml对应于您的问题中提供的XML。

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); 
    } 

} 

对于更多Inforation

+1

谢谢!我会给它一个! – fbl

+0

啊,我遇到了一个小障碍......我的应用程序需要支持插件,'@XmlSeeAlso({Cat.class,Dog.class})'意味着我需要在编译时了解我的后代。有什么办法呢? – fbl

+0

@fbl - 您不需要使用XmlSeeAlso,但JAXBContext需要知道子类。您可能会发现以下方法更适合:http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html –