2011-10-21 26 views
3

我正在處理由第三方編寫的一組模式描述符文件。我需要爲它們生成JAXB存根。每個XSD都定義了一個不同的消息類型,以及一些支持簡單和複雜的類型。許多類型對於每個XSD都是通用的,但不是將它們分解爲單獨的XSD,作者選擇在每個名稱空間中定義它們。當我嘗試使用xjc將XSD編譯成單個包時,這會產生一堆名稱空間衝突。我被迫將它們分成獨特的包。問題在於,這使得它們在應該是時不可互換。我必須做很多額外的轉換才能使用不同消息類型中的一種消息類型的數據。如何解決第三方XML模式衝突?

我的問題:有沒有辦法(綁定定製?)我可以指示xjc爲每個共享類型使用一個java類,而不是遍佈不同包的唯一類?

這是一個簡化的例子。我有兩個XSD,一個用於插入消息,另一個用於響應消息。該響應旨在引用插入消息。

<!-- insert.xsd --> 
<xs:schema 
    xmlns="msg.insert" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="msg.insert"> 

    <xs:element name="Message" type="Message" /> 

    <xs:complexType name="Message"> 
     <xs:sequence> 
      <xs:element 
       maxOccurs="1" 
       minOccurs="1" 
       name="MessageId" 
       type="Identifier" /> 

      <xs:element 
       maxOccurs="1" 
       minOccurs="1" 
       name="SequenceId" 
       type="Identifier" /> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="Identifier"> 
     <xs:sequence> 
      <xs:element 
       maxOccurs="1" 
       minOccurs="1" 
       name="ID" 
       type="xs:string" /> 

      <xs:element 
       maxOccurs="1" 
       minOccurs="1" 
       name="Created" 
       type="xs:dateTime" /> 
     </xs:sequence> 
    </xs:complexType> 

</xs:schema> 

這裏的第二XSD ...

<!-- response.xsd --> 
<xs:schema 
    xmlns="msg.response" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="msg.response"> 

    <xs:element name="Message" type="Message" /> 

    <xs:complexType name="Message"> 
     <xs:sequence> 
      <xs:element 
       maxOccurs="1" 
       minOccurs="1" 
       name="MessageId" 
       type="Identifier" /> 

      <xs:element 
       maxOccurs="1" 
       minOccurs="1" 
       name="SequenceId" 
       type="Identifier" /> 

      <xs:element 
       maxOccurs="1" 
       minOccurs="1" 
       name="ReferenceId" 
       type="Identifier" /> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="Identifier"> 
     <xs:sequence> 
      <xs:element 
       maxOccurs="1" 
       minOccurs="1" 
       name="ID" 
       type="xs:string" /> 

      <xs:element 
       maxOccurs="1" 
       minOccurs="1" 
       name="Created" 
       type="xs:dateTime" /> 
     </xs:sequence> 
    </xs:complexType> 

注意Identifier複雜類型是在兩種模式是相同的。它可以和應該在消息類型之間可以互換。但是,當我運行XJC這樣......

xjc -d java -p example.msg insert.xsd response.xsd

...我得到的消息,標識符和的ObjectFactory類的碰撞如下。

[ERROR] A class/interface with the same name "example.msg.Message" is already in use. Use a class customization to resolve this conflict. 
    line 8 of insert.xsd 

[ERROR] (Relevant to above error) another "Message" is generated from here. 
    line 8 of response.xsd 

[ERROR] A class/interface with the same name "example.msg.Identifier" is already in use. Use a class customization to resolve this conflict. 
    line 15 of insert.xsd 

[ERROR] (Relevant to above error) another "Identifier" is generated from here. 
    line 16 of response.xsd 

[ERROR] Two declarations cause a collision in the ObjectFactory class. 
    line 8 of insert.xsd 

[ERROR] (Related to above error) This is the other declaration. 
    line 8 of response.xsd 

我完全理解爲什麼XJC抱怨,我試圖找到一種方法來哄XJC到使用一個共同的類標識符類型,以及解決ObjectFactory類的衝突。一種解決方案是將常見類型分解到單獨的名稱空間中,並從每個消息類型的XSD中引用它們,但是如前所述,這些都是由第三方編寫的,我無法更改它們。

現在我正在編譯每個XSD到一個單獨的java包。這可行,但非常非常麻煩。

錯誤輸出表明有一種方法可以通過綁定自定義來實現,但到目前爲止我還沒有弄清楚如何完成這項工作。任何人都可以將我指向正確的方向嗎?

+0

我對JAXB並不瞭解,但我的猜測是,你將遇到一個根本性問題,試圖獲得你想要的。您有兩種不同的「標識符」類型,因爲它們位於兩個不同的名稱空間中,這意味着它們必須以不同的方式進行編碼。如果JAXB旨在支持從同一個類生成不同的編碼,我會感到驚訝。 – Kevin

+0

恐怕你是對的,但錯誤輸出說類定製可以解決問題。我仍然試圖弄清楚。 – schufty

+0

我放棄了。我看到如何更改生成的類的名稱,但我看不到如何更改該包。 元素上有一個implClass屬性,但它似乎沒有做任何事情。 – schufty

回答

2

你可以通過添加在的wsimport命令下面的自定義精氨酸解決這個問題:

-B-XautoNameResolution (without spaces) 

這樣一來,任何名稱衝突會自動解析XML時取出。

希望這有助於

0

我不得不處理類似問題具有較大率的XSD之間重複類型的編譯XSD的一個巨大的圖書館(> 1.8K XSD文件)。

我發現的唯一可行的解​​決方案是爲每個名稱空間生成一個默認包的中間模型,然後用Java codemodel將所有類型類移動到一個包中,然後合併重複的類。

最後,我必須破解封送類以避免在摺疊類中感知名稱空間。

這似乎是一個瘋狂的解決方案,但工作得很好。

BTW -XautoNameResolution只是一種自動重命名重複類型類的方法,但它不能解決重複問題。