17

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

<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>

スキーマ クラスは "example" で生成されますが (正しい)、XmlAdapters は "org.w3._2001.xmlschema" で生成されます (誤り)。どうすればこれを修正できますか?

4

5 に答える 5

10

GlobalBinding を使用するより良い方法は、この解析/印刷ペアを使用する代わりに、明示的なアダプターを指定することです。たとえば、次の代わりに:

<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 を使用しないことが非常に重要です。たとえば、プロジェクト A とプロジェクト B が 1 つずつあり、両方にスキーマとバインディングがあるとします。古い方法では、どちらもまったく同じ完全修飾名 (例: org.w3._2001.xmlschema.Adapter1) を持つアダプターを生成します。ただし、このアダプターは、プロジェクト A では Long 用であり、プロジェクト B では Integer 用である可能性があります。次に、A と B の両方を使用するダウンストリーム プロジェクト C があるとします。ここで、問題は厄介になります。C が Adapter1 を使用する必要がある場合、Long の場合は A から、Integer の場合は B から使用されるとは予測できません。次に、アプリケーション C は、しばらくは正常に動作するかもしれませんが、他の状況では奇妙な方法で失敗する可能性があります。これが発生した場合、型例外は次のようになります。

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

Roy Truelove が言及した解決策は、理論が正しい場合でも、自分の環境で maven-jaxb2-plugin を使用して試してみるとうまくいかないようです。

于 2016-08-26T08:56:09.210 に答える
8

I had this problem as well, solved it using this.

The basic premise is that you include a schema in your XJC compilation with following contents:

<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>

You then adjust the package name to where you want the generated adapters to be placed. XJC will believe that this schema is part of the schema set for W3C XML Schema itself and will honour the bindings in it.

于 2011-08-30T15:50:21.530 に答える