【发布时间】:2011-02-03 18:17:54
【问题描述】:
我有一个由 JAXB 生成的类的层次结构。我想将子类编组为基类元素(但具有所有子类属性),使用 xsi:type 来指示具体类型。
例如,给定一个 Animal 和一个 Bird 子类:
<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"/>
无论我如何编组一只鸟,例如:
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);
结果总是一个 Bird 元素:
<Bird xmlns="http://mycompany.com/animals">
<name>Sparrow</name>
<maxAltitude>1000</maxAltitude>
</Bird>
然而我想要的是这个(子类的所有属性,xsi类型,基类元素名称):
<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>
奇怪的是,如果我创建一个包装元素:
<xs:complexType name="animalWrapper">
<xs:sequence>
<xs:element name="Animal" type="animal"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AnimalWrapper" type="animalWrapper"/>
并编组它,它使用基类类型:
<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>
如果我手动构建所需的 XML 文档,JAXB 可以毫无问题地解组它。如何创作我的 XML 模式和/或配置 JAXB 以允许我想要的编组行为?
谢谢。
【问题讨论】:
标签: java xsd jaxb polymorphism