如何使用JAXB将继承的类编组为XML?

时间:2012-03-07 05:19:30

标签: jaxb

我已经提供了一个xsd,我使用JAXB编译为Java类。

生成的类创建一个名为“Event”的抽象类和几个扩展它的类 例如“DerivedEvent” 我使用以下内容将其编组为XML。

ObjectFactory objectFactory = new ObjectFactory();
DerivedEvent derivedEvent = objectFactory.createDerivedEvent();

JAXBContext context = JAXBContextImpl.newInstance("com.my.root.namespace");
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

Class partialClass = Event.class;
QName partNamespace = new QName(Event.class.getSimpleName());
Object element = new JAXBElement(partNamespace, partialClass, derivedEvent);
// Create a stringWriter to hold the XML
StringWriter stringWriter = new StringWriter();
marshaller.marshal(element, stringWriter);
String xml = stringWriter.toString(); 

然后输出错误的根元素。即。

<Event xsi:type="DerivedEvent" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <DerivedStartPeriod xsi:nil="true"/>
    <DerivedEndPeriod xsi:nil="true"/>
</Event>

而不是

<DerivedEvent>
    <DerivedStartPeriod xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
    <DerivedEndPeriod xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</DerivedEvent>

如果我将partialClass和partNamespace设置为DerivedEvent,它会输出正确的信息。 但是,我不能真的这样做,因为这个编组是在一个流程中,事件可能是50个不同派生事件之一。

我无法真正更改xsd以拥有此处http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html所述的替换组,因为当我获得xsd的新版本时,此更改可能会丢失。

我需要使用partial类和命名空间,因为Events不是根元素 我可以以某种方式将事件添加到带有绑定的XmlRootElements吗? 或者还有另一种解决方法吗?

2 个答案:

答案 0 :(得分:1)

通过生成的ObjectFactory创建JAXBElement,或使用正确的QName。 这很糟糕:

QName partNamespace = new QName(Event.class.getSimpleName());

应该是这样的

QName partNamespace = new QName("your namespace", "DerivedEvent");

你应该在ObjectFactory中找到这样的qname,可能是常数...... ObjectFactory可能包含方法createDerivedEvent,其中一个参数类型为DerivedEvent。它返回JAXBElement,可以封送到xml。

答案 1 :(得分:1)

我最终找到了帮助我添加XmlRootElement的页面:
https://codereview.stackexchange.com/questions/1877/jaxb-xjc-code-generation-adding-xmlrootelement-and-joda-datetime

我在这里使用Annotate示例工作了(dependencies / build.xml等):
http://confluence.highsource.org/display/J2B/Home