2013-01-16 81 views
3

我正在使用JAXB從生成幾個XSD文件的Java代碼。然後,在一個OSGi容器中,我將XML文件解組到生成的代碼中。該XSD使用XSD:任何元素:如何強制生成@XmlSeeAlso註釋?

<xsd:complexType name="GetReservationRSType"> 
    <xsd:sequence> 
     <xsd:element name="Errors" type="pnrb:Errors.PNRB" 
      minOccurs="0" /> 
     <xsd:choice> 
      <xsd:element name="Reservation" type="pnrb:Reservation.PNRB" 
       minOccurs="0" /> 
      <xsd:element name="Content" minOccurs="0"> 
       <xsd:complexType> 
        <xsd:choice> 
         <xsd:any processContents="lax" /> 
        </xsd:choice> 
       </xsd:complexType> 
      </xsd:element> 
     </xsd:choice> 
    </xsd:sequence> 
</xsd:complexType> 

我有幾個問題,使得它在生產代碼的工作,但最終我解決了它,當我手動添加註釋@XmlSeeAlso(@XmlSeeAlso(value = { OTATravelItineraryRS.class })在下面的代碼):

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "GetReservationRSType", propOrder = { 
    "warnings", 
    "errors", 
    "reservation", 
    "content" 
}) 
@XmlSeeAlso({ 
    GetReservationRS.class 
}) 
public class GetReservationRSType { 

    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "", propOrder = { 
     "any" 
    }) 
    @XmlSeeAlso(value = { OTATravelItineraryRS.class }) 
    public static class Content { 
     // ... 
    } 
    // ... 
} 

有什麼辦法可以強制JAXB自動添加這樣的註釋嗎?例如,通過添加一些JAXB綁定配置選項或通過修改XSD文件?

編輯:

我JAXBContext而在OSGi的ENV以下列方式進行初始化(它得到所有生成的包名作爲參數) - 他們都列出了冒號分隔符的使用,因爲它是在幾個JAXB-建議相關文章:

<bean id="jaxbContext" class="javax.xml.bind.JAXBContext" factory-method="newInstance"> 
    <constructor-arg index="0" value="com.sabre.webservices.pnrbuilder:com.sabre.webservices.sabrexml._2003._07" />  
</bean>  

我得到以下異常:

Caused by: javax.xml.bind.MarshalException 
- with linked exception: 
[javax.xml.bind.JAXBException: class com.sabre.webservices.sabrexml._2003._07.OTATravelItineraryRS nor any of its super class is known to this context.] 
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:318) 
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244) 
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:105) 
    at org.apache.camel.converter.jaxb.FallbackTypeConverter.marshall(FallbackTypeConverter.java:174) 
    at org.apache.camel.converter.jaxb.FallbackTypeConverter.convertTo(FallbackTypeConverter.java:88) 
    ... 94 more 
Caused by: javax.xml.bind.JAXBException: class com.sabre.webservices.sabrexml._2003._07.OTATravelItineraryRS nor any of its super class is known to this context. 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:246) 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:261) 
    at com.sun.xml.bind.v2.runtime.property.SingleReferenceNodeProperty.serializeBody(SingleReferenceNodeProperty.java:113) 
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332) 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:699) 
    at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152) 
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332) 
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:328) 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:593) 
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:320) 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494) 
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315) 
    ... 98 more 
Caused by: javax.xml.bind.JAXBException: class com.sabre.webservices.sabrexml._2003._07.OTATravelItineraryRS nor any of its super class is known to this context. 
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:590) 
    at com.sun.xml.bind.v2.runtime.property.SingleReferenceNodeProperty.serializeBody(SingleReferenceNodeProperty.java:105) 
    ... 107 more 
+0

AFAIK jaxb在模式中有一些擴展時會生成@XmlSeeAlso。 –

回答

3

我發現了一個令人滿意的解決方法。它使用jaxb annotate plugin。也許這不是完美的解決方案,但 - 至少 - 它阻止我將生成的類提交到SVN存儲庫。提到的插件只需添加想要的註釋。

這裏是必需的配置在的pom.xml

 <plugin> 
      <groupId>org.jvnet.jaxb2.maven2</groupId> 
      <artifactId>maven-jaxb2-plugin</artifactId> 

      <executions> 
       <execution> 
        <id>schema-pnr-service</id> 
        <goals> 
         <goal>generate</goal> 
        </goals> 
        <configuration> 
         <schemaDirectory>src/main/resources/xsd</schemaDirectory> 
         <schemaIncludes> 
          <include>GetReservationSTLRQ_v0.01.xsd</include> 
          <include>GetReservationSTLRS_v0.01.xsd</include> 
          <include>OTA_TravelItineraryReadCDI1.0.5RQ.xsd</include> 
          <include>OTA_TravelItineraryReadCDI1.0.5RQRS.xsd</include> 
          <include>OTA_TravelItineraryReadCDI1.0.5RS.xsd</include> 
          <include>OTA_TravelItineraryReadPNR1.0.5RS.xsd</include> 
         </schemaIncludes> 
         <extension>true</extension> 
         <args> 
          <arg>-Xannotate</arg> 
          <arg>-Xannotate-defaultFieldTarget=setter</arg> 
         </args> 
         <plugins> 
          <plugin> 
           <groupId>org.jvnet.jaxb2_commons</groupId> 
           <artifactId>jaxb2-basics-annotate</artifactId> 
          </plugin> 
         </plugins>        
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 

而且有用的註釋中bindings.xjb文件,應該在同一個目錄中* xsd文件被配置爲 - 這裏是它的內容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" 
       xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd" 
       xmlns:annox="http://annox.dev.java.net" 
       extensionBindingPrefixes="annox" version="2.1"> 
    <globalBindings typesafeEnumMaxMembers="600"/> 

    <bindings schemaLocation="GetReservationSTLRS_v0.01.xsd" node="/xsd:schema"> 
     <bindings node="xsd:complexType[@name='GetReservationRSType']/xsd:sequence/xsd:choice/xsd:element[@name='Content']/xsd:complexType"> 
      <annox:annotate target="class"> 
       <annox:annotate annox:class="javax.xml.bind.annotation.XmlSeeAlso" value="com.sabre.webservices.sabrexml._2003._07.OTATravelItineraryRS" /> 
      </annox:annotate>   
     </bindings> 

    </bindings>  
</bindings> 
0

而不是試圖在@XmlSeeAlso安給力您應該在生成的軟件包名稱上創建JAXBContext。這樣你就可以確定所有的類都被處理了。由於您處於OSGi環境中,因此請使用採用ClassLoader參數的方法之一。

JAXBContext jc = JAXBContext.newInstance("com.example.foo", ObjectFactory.class.getClassLoader()); 

如果有多於一個的產生的包名稱,則上下文路徑是:界定。

JAXBContext jc = JAXBContext.newInstance("com.example.foo:org.example.bar", ObjectFactory.class.getClassLoader()); 
+0

這似乎不起作用 - 請參閱我的編輯。 – Lukasz

+0

'ClassLoader'參數非常重要。你發佈什麼類型的配置文件? –

+0

這是標準的Spring beans.xml文件。然後將jaxbContext bean注入到實際負責解組的其他bean中。 – Lukasz