6

XJC を使用して XSD から Java POJO を生成するアプリケーションに取り組んでいます。数十のスキーマがあり、その数は増えるでしょう。また、アプリケーションは、同じスキーマの異なるバージョンを処理できる必要があります。つまり、共通の型を定義する複数のスキーマを持つことになります。特定のコア タイプが共通のインターフェイスを実装するようにバインディングをカスタマイズしようとしています。JAXB2 Basics の Inheritance プラグインは、私が必要としている機能を果たしているようですが、正しい構文を理解できていないようです。

私のスキーマの関連部分は次のとおりです。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:my="http://example.com/core"
           targetNamespace="http://example.com/core"
           xmlns:xml="http://www.w3.org/XML/1998/namespace">

    ...

    <xs:complexType name="addressType">
        <xs:sequence>
            <xs:element name="Address" type="xs:string"/>
            <xs:element name="City" type="xs:string"/>
            <xs:element name="Province" type="xs:string"/>
            <xs:element name="Country" type="xs:string"/>
            <xs:element name="County" type="xs:string" minOccurs="0"/>
            <xs:element name="PostalCode" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

    ...

</xs:schema>

...そして、これは私のカスタムバインディングファイルがどのように見えるかです:

    <?xml version="1.0"?>
<jaxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
    xmlns:my="http://example.com/core"
    jaxb:extensionBindingPrefixes="inheritance"
    version="2.1">

    <jaxb:bindings scd="x-schema::my" xmlns:my="http://example.com/core">
        <jaxb:globalBindings localScoping="toplevel">
            <jaxb:serializable/>
            <xjc:simple/>
        </jaxb:globalBindings>
        <jaxb:bindings scd="/type::my:addressType">
            <inheritance:implements>com.mysite.validator.ValidatableAddress</inheritance:implements> 
            <!--<xjc:superInterface name="com.mysite.validator.ValidatableAddress"/>-->
        </jaxb:bindings>
    </jaxb:bindings>

</jaxb:bindings>

継承プラグインの使用方法を示すすべての「従来の」バインディングの例では、schemaLocationが指定されているため、私はscdアプローチを使用しています。スキーマの数が多い (そして増加している) ため、schemaLocationを指定する必要は避けたいと考えています。新しいスキーマを追加するたびにバインディング ファイルを変更する必要はありません。したがって、scdはこの要件を満たしているようです。

ただし、上記のバインディングを使用してビルドを実行すると、次のようになります。

  [xjc] [ERROR] cvc-elt.1: Cannot find the declaration of element 'inheritance:implements'.
  [xjc]   line 18 of file:/dev/workspace/my_app/etc/schemas/bindings-common.xml
  [xjc] failure in the XJC task. Use the Ant -verbose switch for more details
  [xjc] classLoader = java.net.URLClassLoader@ebcdbb
  [xjc] SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@14562c5

inheritance:implements行をコメントアウトし、 xjc:superInterface行のコメントを外すと、エラーはなくなり、ビルドは正常に完了しますが、私のAddressTypeクラスは ValidatableAddress タイプを実装していません。

継承プラグインをscdで使用できますか? xjc:superInterface を特定の要素のみに制限できますか?

乾杯。

4

2 に答える 2

4

の著者はこちら。

XJC でこの問題を参照してください。つまり、何らかの理由で XJC は、SCD バインディングでカスタム/ベンダー カスタマイズ要素を許可しません。
inheritance:implementsそんなカスタマイズ要素です。

いいえ、これは XJC の問題により機能しません。

私は個人的に XPath を介してバインドしschemaLocationますが、「仮想」スキーマの場所 URI を使用し、カタログを介してそれを書き換えます。

SCD の方がはるかに適切な選択でした (まさにそのとおりです) が、うまくいきません。

仮想スキーマの場所とカタログを更新します。

複合型をカスタマイズするバインディングの例を次に示します。

<jaxb:bindings 
    schemaLocation="http://schemas.opengis.net/wps/2.0/wpsCommon.xsd" 
    node="/xs:schema">
    <jaxb:bindings node="xs:element[@name='Data']/xs:complexType">
        <wildcard:lax/>
    </jaxb:bindings>
</jaxb:bindings>

schemaLocationXPathを介してバインドされます。は既存の URLschemaLocationですが、ビルドでは、カタログを介して Maven アーティファクト内のリソースに書き換えられます。

REWRITE_SYSTEM "http://schemas.opengis.net" "maven:org.jvnet.ogc:ogc-schemas:jar::!/ogc"

したがって、基本的http://schemas.opengis.net/wps/2.0/wpsCommon.xsdには からロードされますogc-schema.jar!/ogc/wps/2.0/wpsCommon.xsd

を使用すると、Maven アーティファクト内のバインディング ファイルも参照できます。

                    <binding>
                        <dependencyResource>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>ows-v_2_0</artifactId>
                            <resource>ows-v_2_0.jsonix.xjb</resource>
                            <version>${project.version}</version>
                        </dependencyResource>
                    </binding>

したがって、組み合わせて使用​​すると、バインディング ファイルを 1 回記述すれば、それらをモジュール間で再利用できます。

しかし、これを理解するのは非常に困難でした。私はogc-schemasプロジェクトのためにそれを行いました。これは現在、約 50 の相互接続されたスキーマです。私は XJC の欠点と問題にひどく苦しんでいますが、現時点ではこれが最善の方法です。XJC を fork してパッチを適用することも考えましたが、これは私ができる努力の限界にはほど遠いものです。

だから私は、一日の終わりに何らかの形で仕事をするマインドブログの回避策をいくつか見つけました。

于 2015-06-16T19:04:42.643 に答える
4

迅速かつ詳細な回答を提供してくれたlexicoreに感謝します。しかし、そのアプローチは私にとってはうまくいかなかったので、次の解決策になりました...

私は Ant を使用して XJC を呼び出しているため、Ant の<copy filtering="true"...>機能を利用してバインディング ファイルを動的に生成することになりました。

これが私のバインディング「テンプレート」ファイル (bindings-common.xml) です。

<?xml version="1.0"?>
<jaxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
    xmlns:my="http://http://example.com/core"
    jaxb:extensionBindingPrefixes="inheritance" 
    version="2.1">
    <jaxb:bindings>
        <jaxb:globalBindings localScoping="toplevel">
            <jaxb:serializable/>
            <xjc:simple/>
        </jaxb:globalBindings>
    </jaxb:bindings>

    <jaxb:bindings
        schemaLocation="@bindingSchema@" 
        node="/xs:schema">

        <jaxb:bindings node="//xs:complexType[@name='addressType']">
            <inheritance:implements>com.example.validator.ValidatableAddress</inheritance:implements>
        </jaxb:bindings>
    </jaxb:bindings>

</jaxb:bindings>

次の行に注意してください。

<jaxb:bindings
            schemaLocation="@bindingSchema@" 
            node="/xs:schema">

この変数は、処理中のスキーマごとに Ant によって設定されます。

<property name="jaxb.binding.template" value="../etc/form-schemas/bindings-common.xml"/>
<property name="jaxb.binding.file" value="${jaxb.src.dir}/bindings-common${schema.version}.xml"/>

<echo message="Filtering ${jaxb.binding.file} using template ${jaxb.binding.template}"/>

<copy file="${jaxb.binding.template}" 
      tofile="${jaxb.binding.file}"
      filtering="true">

    <filterset>
        <filter token="bindingSchema" value="../../etc/form-schemas/${schema.version}/common.xsd"/>
    </filterset>
</copy>

<xjc destdir="${jaxb.src.dir}" 
        extension="true" 
        schema="${schema.file}" 
        package="${package}" 
        binding="${jaxb.binding.file}">

    <arg value="-episode"/> 
    <arg value="${jaxb.src.dir}/common${schema.version}.episode"/> 
    <arg line="-Xinheritance"/>

        <!-- Plugins -->
        <classpath>
            <fileset dir="../build-libs/">
                <!-- JAXB2 Basics library -->
                <include name="jaxb2-basics-0.6.4.jar"/>
                <!-- JAXB2 Basics library dependencies -->
                <include name="jaxb2-basics-runtime-0.6.4.jar"/>
                <include name="jaxb2-basics-tools-0.6.4.jar"/>
                <include name="javaparser-1.0.8.jar"/>
                <include name="commons-beanutils-*.jar"/>
                <include name="commons-lang-*.jar"/>
                <include name="commons-logging-*.jar"/>
            </fileset>
        </classpath>
    </xjc>
</target>

これが将来の世代の JAXB 被害者に役立つことを願っています。

于 2015-06-18T14:40:06.087 に答える