JAXB 生成了 类 某些实现自定义接口的类型
JAXB generated classes of certain types implementing a custom interface
我正在开发一个使用 XJC 从 XSD 生成 Java POJO 的应用程序。模式有几十种,而且这个数字还会增长。应用程序还需要能够处理同一模式的不同版本,这意味着我将有多个模式定义通用类型。我正在尝试自定义绑定,以便某些核心类型实现通用接口。 JAXB2 Basics 的继承插件似乎可以满足我的需要,但我似乎无法确定正确的语法。
这是我的架构的相关部分:
<?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>
我正在使用 scd 方法,因为在显示如何使用继承插件的所有 "traditional" 绑定示例中,schemaLocation 被指定。我想避免必须指定 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@14562c5
如果我注释掉 inheritance:implements 行并取消注释 xjc:superInterface 行,错误就会消失,并且构建成功完成,但我的 AddressType 类 没有实现 ValidatableAddress 类型。
继承插件可以和scd一起使用吗?可以 xjc:superInterface 仅限于某些元素吗?
干杯。
jaxb2-basics 的作者在这里。
请参阅 XJC 中的 this issue。简而言之,出于某种原因,XJC 不允许 custom/vendor SCD 绑定中的自定义元素。
inheritance:implements
就是这样的自定义元素。
所以不,由于 XJC 中的问题,这不起作用。
我个人通过 schemaLocation
和 XPath 进行绑定,但使用 "virtual" 架构位置 URI 并通过目录重写它。
SCD 本来是一个更好的选择(你完全正确)但它就是行不通。
更新 虚拟架构位置和目录。
这里有一个 example of binding 自定义一些复杂的类型:
<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>
它是通过 schemaLocation
和 XPath 绑定的。 schemaLocation
是 Maven 工件内资源的 existing URL, but in the build it is rewritten via catalog:
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-jaxb2-plugin you can refer to binding files inside Maven artifacts as well:
<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>
因此,结合起来,它允许编写一次绑定文件并跨模块重用它们。
但这一切都是一个巨大的痛苦。我为 ogc-schemas project which is now some 50 heavily interconnected schemas. I heavily suffer from XJC drawbacks and issues, but this is the best possible at the moment. I even thought about forking and patching XJC 做到了,但这是我所能承受的努力极限。
所以我最终得到了一些 mindblogging 变通办法,这些变通办法在一天结束时以某种方式完成了工作。
感谢 lexicore 及时而详细的回答。但是这种方法对我不起作用,所以我最终得到了以下解决方案...
因为我使用 Ant 来调用 XJC,所以我最终利用 Ant 的 <copy filtering="true"...>
功能来动态生成绑定文件。
这是我的绑定 "template" 文件 (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 受害者有所帮助。
我正在开发一个使用 XJC 从 XSD 生成 Java POJO 的应用程序。模式有几十种,而且这个数字还会增长。应用程序还需要能够处理同一模式的不同版本,这意味着我将有多个模式定义通用类型。我正在尝试自定义绑定,以便某些核心类型实现通用接口。 JAXB2 Basics 的继承插件似乎可以满足我的需要,但我似乎无法确定正确的语法。
这是我的架构的相关部分:
<?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>
我正在使用 scd 方法,因为在显示如何使用继承插件的所有 "traditional" 绑定示例中,schemaLocation 被指定。我想避免必须指定 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@14562c5
如果我注释掉 inheritance:implements 行并取消注释 xjc:superInterface 行,错误就会消失,并且构建成功完成,但我的 AddressType 类 没有实现 ValidatableAddress 类型。
继承插件可以和scd一起使用吗?可以 xjc:superInterface 仅限于某些元素吗?
干杯。
jaxb2-basics 的作者在这里。
请参阅 XJC 中的 this issue。简而言之,出于某种原因,XJC 不允许 custom/vendor SCD 绑定中的自定义元素。
inheritance:implements
就是这样的自定义元素。
所以不,由于 XJC 中的问题,这不起作用。
我个人通过 schemaLocation
和 XPath 进行绑定,但使用 "virtual" 架构位置 URI 并通过目录重写它。
SCD 本来是一个更好的选择(你完全正确)但它就是行不通。
更新 虚拟架构位置和目录。
这里有一个 example of binding 自定义一些复杂的类型:
<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>
它是通过 schemaLocation
和 XPath 绑定的。 schemaLocation
是 Maven 工件内资源的 existing URL, but in the build it is rewritten via catalog:
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-jaxb2-plugin you can refer to binding files inside Maven artifacts as well:
<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>
因此,结合起来,它允许编写一次绑定文件并跨模块重用它们。
但这一切都是一个巨大的痛苦。我为 ogc-schemas project which is now some 50 heavily interconnected schemas. I heavily suffer from XJC drawbacks and issues, but this is the best possible at the moment. I even thought about forking and patching XJC 做到了,但这是我所能承受的努力极限。
所以我最终得到了一些 mindblogging 变通办法,这些变通办法在一天结束时以某种方式完成了工作。
感谢 lexicore 及时而详细的回答。但是这种方法对我不起作用,所以我最终得到了以下解决方案...
因为我使用 Ant 来调用 XJC,所以我最终利用 Ant 的 <copy filtering="true"...>
功能来动态生成绑定文件。
这是我的绑定 "template" 文件 (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 受害者有所帮助。