質問

このようなバインディングファイルがあります

<jxb:bindings version="2.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <jxb:bindings schemaLocation="example.xsd" node="/xs:schema">
    <jxb:schemaBindings>
        <jxb:package name="example" />
    </jxb:schemaBindings>
    <jxb:globalBindings>
        <jxb:javaType name="java.util.Calendar" xmlType="xs:dateTime"
            parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime"
            printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />
        <jxb:javaType name="java.util.Calendar" xmlType="xs:date"
            parseMethod="javax.xml.bind.DatatypeConverter.parseDate"
            printMethod="javax.xml.bind.DatatypeConverter.printDate" />
        <jxb:javaType name="java.util.Calendar" xmlType="xs:time"
            parseMethod="javax.xml.bind.DatatypeConverter.parseTime"
            printMethod="javax.xml.bind.DatatypeConverter.printTime" />
    </jxb:globalBindings>

  </jxb:bindings>
</jxb:bindings>

スキーマクラスは「例」(正しい)で生成されますが、「org.w3._2001.xmlschema」(間違った)のxmladaptersが生成されます。どうすればこれを修正できますか?

役に立ちましたか?

解決

私もこの問題を抱えていました、それを使って解決しました これ.

基本的な前提は、次のコンテンツを含むXJCコンピレーションにスキーマを含めることです。

<schema xmlns="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.w3.org/2001/XMLSchema"
  xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
  jaxb:version="2.0">
  <annotation><appinfo>
    <jaxb:schemaBindings>
      <jaxb:package name="org.acme.foo"/>
    </jaxb:schemaBindings>
  </appinfo></annotation>
</schema>

次に、生成されたアダプターを配置する場所にパッケージ名を調整します。 XJCは、このスキーマはW3C XMLスキーマ自体のスキーマセットの一部であり、そのバインディングを称えると信じています。

他のヒント

org.w3._2001.xmlschema XJCが拡張するクラスを生成する必要があるため、パッケージはここで作成されます javax.xml.bind.annotation.adapters.XmlAdapter, 、それはあなたの解析/印刷の静的メソッドを呼び出します。何らかの理由で、より便利な場所ではなく、このパッケージに入れます。

どのjaxb実装を使用しているかについては言いませんが、Jaxb Riには javaType のサブクラスを指定できるバインディングカスタマイズ XmlAdapter 直接、ではなく parseMethod/printMethod ペア。これにより、合成を生成する必要性が削除されます XmlAdapter ブリッジクラス。を参照してください RIドキュメント これを行う方法のために。

Eclipselink/Moxyにはこれに似たものがあると思いますが、Java6に出荷するXJCがそれができるかどうかはわかりません(太陽はJREに持ち込んだときにRIから有用なものの半分を除去したようです) 。

Apache CXFユーザーの場合、最もクリーンな方法は -p によって提供されるオプション wsdl2java.

-p [wsdl-namespace =] packageName

生成されたコードに使用するゼロ、またはそれ以上のパッケージ名を指定します。オプションでは、WSDL名空間をパッケージ名マッピングに指定します。

私たちの場合には

-p http://www.w3.org/2001/XMLSchema=org.acme.foo

cxf-codegen-pluginを使用する場合は、別のペアを追加するだけです <extraarg>.

<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>${cxf.version}</version>
        [...]
    <extraarg>-p</extraarg>
    <extraarg>http://www.w3.org/2001/XMLSchema=org.acme.foo</extraarg>
        [...]
</plugin>

予約されたXSDネームスペースを指すTargetNamesSpaceの必要はなく、Catch-All JaxBパッケージバインディングは必要ありません。

グローバルバインディングを使用するより良い方法は、この解析/印刷ペアを使用する代わりに明示的なアダプターを指定することです。たとえば、以下の代わりに:

<jaxb:javaType name="java.lang.Long" xmlType="xs:long"
                      parseMethod="com.mypackage.myclass.parseLong"
                  printMethod="com.mypackage.myclass.print"/>

代わりに、次のようにする必要があります。

<xjc:javaType name="java.lang.Long" xmlType="xs:long"
                  adapter="com.mypackage.LongAdapter"/>

XJCの名前空間を追加することを忘れないでください:

xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
          jxb:extensionBindingPrefixes="xjc"

クラスのlongadapterは次のようになります:

public class LongAdapter
extends XmlAdapter<String, Long>
{


public Long unmarshal(String value) {
    return your_util_class.parseLong(value);
}

public String marshal(Long value) {
    return your_util_class.print(value);
}

}

このように、アダプタークラスを明示的に指定したため、JaxBはデフォルトのパッケージ名org.w3._2001.xmlschemaでデフォルトアダプターを生成しません。

デフォルトのパッケージ名org.w3._2001.xmlschemaを使用することを避けることは非常に重要です。 1つの例を挙げて、1つのプロジェクトAと1つのプロジェクトBがあり、両方ともスキーマとバインディングがある場合。古い方法では、どちらもまったく同じ完全な名前のアダプターを生成します。ただし、このアダプターはプロジェクトAで長く、プロジェクトBでは整数の場合、AとBの両方を使用してダウンストリームプロジェクトCがあるとしましょう。これで問題は厄介になります。 Cがadapter1を使用する必要がある場合、使用済みのものは長いAから、または整数のBから予測することはできません。その後、アプリケーションCはしばらくの間正常に動作する可能性がありますが、他の状況では奇妙な方法で失敗する可能性があります。これが発生した場合、タイプの例外は次のようになります。

org.w3._2001.xmlschema.Adapter1 is not applicable to the field type java.lang.Double...

Roy Trueloveが言及したソリューションは、理論が正しい場合でもMaven-Jaxb2-Pluginを使用して環境で試してみたときに機能しないようです。

一般的なデータタイプに組み込まれたコンバーターを使用します。

<jxb:javaType name="java.lang.Integer" xmlType="xs:integer"              
parseMethod="javax.xml.bind.DatatypeConverter.parseInt"                  
printMethod="javax.xml.bind.DatatypeConverter.printInt" />
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top