不可能在超类型上注释属性,并尝试将子尝试增量添加到该映射中。以下是您可以支持您所追求的所有用例的一种方法。需要注意的一件事是对象层次结构中的所有级别都支持同一组元素。您需要使用外部验证方法来限制所需的值。
If Thing
是一个类而不是一个接口,并且First
and Second
extend Thing
那么你可能有兴趣使用@XmlElementRef
代替@XmlElements
(see: http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html)。它将为您提供更大的灵活性,但需要进行一些验证(很难限制有效值的集合)。
Bar
我们将注释Bar
with @XmlTransient
这样 JAXB 实现就不会处理它。
package forum11698160;
import java.util.List;
import javax.xml.bind.annotation.XmlTransient;
@XmlTransient
public abstract class Bar extends Foo {
public List<Thing> getThings() {
return super.getThings();
}
}
Bobar
@XmlElementRef
对应于 XML 模式中替换组的概念。与属性匹配的值将基于@XmlRootElement
声明。
package forum11698160;
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class Bobar extends Bar {
@XmlElementRef
public List<Thing> getThings() {
return super.getThings();
}
}
Thing
由于 JAXB 实现无法使用反射来查找某个类型的所有子类,因此我们可以使用@XmlSeeAlso
注释来帮忙。如果您不使用此注释,那么您将需要在引导时包含所有子类型JAXBContext
.
package forum11698160;
import javax.xml.bind.annotation.XmlSeeAlso;
@XmlSeeAlso({First.class, Second.class})
public class Thing {
}
First
我们需要注释First
with @XmlRootElement
:
package forum11698160;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class First extends Thing {
}
Second
Second
还需要注释@XmlRootElement
:
package forum11698160;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Second extends Thing {
}
Demo
package forum11698160;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Bobar.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum11698160/input.xml");
Bobar bobar = (Bobar) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(bobar, System.out);
}
}
输入.xml/输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bobar>
<first/>
<second/>
</bobar>
其他文件
以下是运行此示例所需的其他文件:
Foo
package forum11698160;
import java.util.*;
public abstract class Foo {
private List<Thing> things = new ArrayList<Thing>();
public List<Thing> getThings() {
return this.things;
}
}