2012-03-07 35 views
1

我已經提供了一個使用JAXB編譯爲Java類的xsd。如何使用JAXB將繼承的類編組爲XML?

生成的類創建一個名爲「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提供新版本時,此更改很可能會丟失。

我需要使用部分類和名稱空間作爲事件不是根元素。
我可以通過某種方式將事件添加爲XmlRootElements嗎?
或者有另一種解決方法嗎?

回答

1

通過生成的ObjectFactory創建JAXBElement,或使用適當的QName。 這是不好:

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

它應該是這樣的

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

你應該找到的QName像這樣ObjectFactory可能是因爲常... ObjectFactory可能含有方法createDerivedEvent型DerivedEvent的一個參數。它返回可以封送到xml的JAXBElement。