JAXB生成了实现自定义接口的某些类型的类 [英] JAXB generated classes of certain types implementing a custom interface

查看:80
本文介绍了JAXB生成了实现自定义接口的某些类型的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用XJC从XSD生成Java POJO的应用程序。有几十种模式,这个数字会增长。应用程序还需要能够处理相同模式的不同版本,这意味着我将有多个模式定义常见类型。我正在尝试自定义绑定,以便某些核心类型实现一个通用接口。 JAXB2 Basics的继承插件似乎做了我需要的东西,但我似乎无法确定正确的语法。

I am working on an application that uses XJC to generate Java POJOs from XSDs. There are dozens of schemas, and that number will grow. The application also needs to be able to handle different versions of the same schema, which means that I will have multiple schemas defining common types. I am trying to customize the bindings so that certain core types implement a common interface. The Inheritance plugin of JAXB2 Basics seems to do what I need, but I can't seem to nail the right syntax.

以下是我的架构的相关部分:

Here is the relevant part of my schema:

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

...这就是我的自定义绑定文件:

... and this is what my custom binding file looks like:

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

我正在使用 scd 方法,因为在所有传统指定了如何使用继承插件的绑定示例, schemaLocation 。我想避免必须指定 schemaLocation ,因为我们的模式数量很大(且不断增长)。我不想每次添加新架构时都要更改绑定文件。所以, scd 似乎会满足这个要求。

I'm using the scd approach, because in all the "traditional" binding examples that show how to use the inheritence plugin, schemaLocation is specified. I want to avoid having to specify schemaLocation because of our large (and growing) number of schemas. I don't want to have to change the binding file every time we add a new schema. So, scd seems like it will satisfy this requirement.

但是当我使用上面的绑定运行构建时,我得到了这个:

However when I run the build using the above binding, I get this:


  [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


如果我注释掉继承:implements 行和取消注释 xjc:superInterface 行,错误消失,构建成功完成,但我的 AddressType 类没有实现ValidatableAddress类型。

If I comment out the inheritance:implements line and uncomment the xjc:superInterface line, the error goes away and the build completes successfully, but my AddressType classes don't implement the ValidatableAddress type.

继承插件可以与 scd 一起使用吗? xjc:superInterface可以仅限于某些元素吗?

Can the inheritence plugin be used with scd? Can xjc:superInterface be limited to only certain elements?

干杯。

推荐答案

感谢词典提供快速而详细的答案。然而,这种方法对我不起作用,所以我最终得到了以下解决方案......

Thanks to lexicore for the prompt and detailed answers. However that approach wasn't working for me, so I ended up with the following solution...

因为我使用Ant来调用XJC,所以我最终利用了Ant的< copy filtering =true...> 动态生成绑定文件的功能。

Because I am using Ant to invoke XJC, I ended up leveraging Ant's <copy filtering="true"...> capabilities to dynamically generate the binding file.

此处是我的绑定模板文件(bindings-common.xml):

Here is my binding "template" file (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将填充此变量:

This variable will get populated by Ant for each of the schemas that I am processing:

<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受害者。

Hopefully this will help future generations of JAXB victims.

这篇关于JAXB生成了实现自定义接口的某些类型的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆