2011-10-21 9 views
3

私は第三者が作成した一連のスキーマ記述ファイルを扱っています。 JAXBスタブを生成する必要があります。各XSDは、さまざまな種類のメッセージをサポートするシンプルタイプと複合タイプを定義します。多くのタイプは各XSDに共通ですが、別々のXSDにそれらを取り除くのではなく、各名前空間でそれらを定義することを選択しました。これは、xjcを使ってXSDを単一のパッケージにコンパイルしようとすると、名前空間の衝突が発生します。私はそれらを一意のパッケージに分けなければなりません。問題は、これにより、これらが交換可能でなくてはならない場合です。あるメッセージタイプのデータを別のメッセージタイプで使用するには、多くの余分な変換が必要です。サードパーティのXMLスキーマの衝突を解決するにはどうすればよいですか?

私の質問:何らかの方法(バインディングのカスタマイズですか?)xjcには、異なるパッケージにまたがっている一意のクラスではなく、各共有タイプに対して1つのJavaクラスを使用するよう指示できますか?

ここでは簡単な例を示します。 2つのXSDがあります.1つは挿入メッセージ用で、もう1つは応答メッセージ用です。この応答は、挿入メッセージを参照するためのものです。ここで

<!-- 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 -d java -p example.msg insert.xsd response.xsd

...私は、メッセージ、識別子、およびObjectFactoryのクラスでの衝突を取得... XJCので、実行したとき。

[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が不平を言っている理由は、私は識別子のタイプに共通のクラスを使用して、同様のObjectFactoryクラスの衝突を解決するにXJC同軸する方法を見つけようとしている理解しています。 1つの解決策は、一般的な型を個別の名前空間に因数分解して各メッセージ型のXSDから参照することですが、これらはすべて第三者によって書かれたものであり、変更する能力はありません。

今のところ、別のJavaパッケージに各XSDをコンパイルしています。これは機能しますが、非常に面倒です。

エラー出力には、バインディングのカスタマイズでこれを行う方法があることが示唆されていますが、これまでのところ、私はその作業を行う方法を理解していません。誰かが私を正しい方向に向けることができますか?

+0

JAXBについてはよくわかりませんが、私が推測するのは、あなたが望むものを手に入れることに根本的な問題があるということです。 2つの異なる名前空間にあるように、2つの異なる「識別子」型があります。つまり、必ず異なる形式でエンコードする必要があります。 JAXBが同じクラスの異なるエンコーディングをサポートするように設計されていれば、私は驚くでしょう。 – Kevin

+0

あなたの意見は間違いですが、クラスのカスタマイズによって問題が解決されるというエラー出力が出ています。私はまだそれを理解しようとしています。 – schufty

+0

私はあきらめます。生成されたクラスの名前を変更する方法は分かりますが、パッケージの変更方法はわかりません。 要素にはimplClass属性がありますが、何もしないようです。 – schufty

答えて

2

あなただけwsimportのコマンドで次のカスタム引数を追加することで、この問題を解決することができます

-B-XautoNameResolution (without spaces) 

この方法は、XMLを解析する際に、任意の名前の競合が自動的に削除されます。

希望これは私がのXSD間の重複種類の大率とXSDの膨大なライブラリー(> 1.8K XSDファイル)をコンパイルするために、同様の問題に対処しなければならなかった

0

に役立ちます。

私が見つけた唯一の実現可能な解決策は、ネームスペースごとにデフォルトパッケージを持つ中間モデルを生成し、その後Javaコードモデルですべてのタイプクラスを単一のパッケージに移動して複製したクラスを折りたたむことでした。

最後に、折りたたまれたクラスで名前空間を認識しないようにマーシャリングをハックする必要がありました。

これはクレイジーなソリューションのようですが、うまく機能しました。

BTW -XautoNameResolutionは重複した型クラスの名前を自動的に変更する方法ですが、重複の問題は解決しません。

関連する問題