2011-12-02 13 views
6

Scala projesinde çalışıyorum ve nesnelerimizi JAXB (İlkbahar değil) ile başlatmak için XML kullanmak istiyoruz. Alt sınıflara daha fazla veri üyesinin eklendiği bir hiyerarşim var. Basit bir örnek şuna benzer olacaktır: Ben şuna benzer bir XML bloktan hayvanların bir listesini başlatmak edebilmek istiyorum JAXB temel sınıflardaki değerleri başlatabilir mi?

class Animal 
{ 
    string name 
} 

class Cat extends Animal 
{ 
    int numLives 
} 

class Dog extends Animal 
{ 
    bool hasSpots 
} 

:

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

nasıl olur biz kurulum Bunu başarabilmek için sınıflardaki ek açıklamaları?

cevap

0

Böyle durumlarda, bir XSD şeması oluşturmayı ve ondan kod üretmeyi tercih ediyorum, bu yüzden güvenli taraftasınız. Ama sorunuzu cevaplamak için evet, yapabilirsiniz. Ek açıklamalar, XMLElement, XMLAttribute, XMLRootElement öğesidir.

3

Bu örnekte, @XmlElementRef ve @XmlRootElement ek açıklamalarını kullanmak isteyeceksiniz. Bu, ikame gruplarının XML şema kavramına karşılık gelir. Bu, öğe tarafından farklılaştırılmış bir kalıtım hiyerarşisindeki nesnelerin bir listesine sahip olmanızı sağlayacaktır.

Hayvanlar

Bu alan modeli için kök nesnesi olarak görev yapacak. @XmlElementRef ile açıklanmış bir List özelliğine sahiptir. Bu, değerlerin @XmlRootElement ek açıklamalarının değerine göre eşleşeceği anlamına gelir.

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

Hayvan

package forum8356849; 

import javax.xml.bind.annotation.*; 

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

Kedi

Biz @XmlRootElement ek açıklamasıyla Cat sınıf açıklama olacaktır. Bu, Animals numaralı @XmlElementRef ek açıklamayla birlikte kullanılır.

package forum8356849; 

import javax.xml.bind.annotation.*; 

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

Köpek

Biz de Dog sınıfa bir @XmlRootElement ek açıklama ekleyecektir.

package forum8356849; 

import javax.xml.bind.annotation.*; 

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

Demo

Sen her şeyin beklendiği gibi çalıştığını görmek için aşağıdaki sınıfını kullanabilirsiniz. input.xml, sorunuzda sağlanan XML'e karşılık gelir. Daha inforation

  • http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html için

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

teşekkürler! Bir şans vereceğim! – fbl

+0

Ahh, biraz şaşırdım ...Uygulamamın eklentileri desteklemesi gerekiyor, '@XmlSeeAlso ({Cat.class, Dog.class}) 'da, derleme zamanında derlemelerimi bilmem gerektiğini ima ediyor. Bunun herhangi bir yolu var mı? – fbl

+0

@fbl - XmlSeeAlso kullanmanız gerekmez, ancak JAXBContext alt sınıfların farkında olmak zorundadır. Aşağıdaki yaklaşımı daha iyi bir şekilde bulabilirsiniz: http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html –