通常,您希望这样做的方式是使用 Schema Component Designators (SCD) 而不是 XPath。
Using SCD for customizations
[XPath] 也容易出错,因为它依赖于模式文档的布局方式,因为 schemaLocation 属性需要指向正确的模式文档文件。当一个模式被拆分为多个文件以实现模块化时(尤其经常发生在大型模式中),那么您必须找到它是哪个模式文件。即使您可以使用相对路径,这种路径信息的硬编码也使得很难将绑定文件传递给其他人。
SCD Support
与标准的基于 XPath 的方法相比,SCD 允许以更健壮和简洁的方式识别自定义目标。有关 SCD 的更多信息,请参阅 scd 示例。请注意,SCD 是 W3C 工作草案,将来可能会更改。
很遗憾,由于bug in XJC,SCD 不能与供应商扩展结合使用。您会看到如下错误:
[ERROR] cvc-elt.1: Cannot find the declaration of element 'inheritance:implements'.
author of jaxb2-basics 最近针对该特定问题撰写了detailed explanation。基本上,如果您想使用供应商扩展,那么您现在只能使用 XPath(及其局限性)。
基于 XPath 的解决方案
根据您在问题中提供的信息,这是一个使用 XPath 和供应商扩展的完整工作示例。我相信从导入的模式生成类的正确方法是通过单独的绑定元素。为了证明这是按预期工作的,从此绑定 (Cust) 生成的类是可见的,并且可以被common.xsd 生成的那些类重用。每个生成的类都实现基类jaxb.BaseMessage。
我相信在 XJC 错误修复之前,这是一个很好的解决方案。
src/main/resources/bindings.xjb:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
jaxb:version="2.1"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
jaxb:extensionBindingPrefixes="xjc inheritance">
<jaxb:globalBindings>
<jaxb:javaType name="java.lang.Long" xmlType="xsd:integer" />
</jaxb:globalBindings>
<jaxb:bindings schemaLocation="schema/x.xsd">
<jaxb:bindings node="//xsd:complexType[@name='Customer']">
<jaxb:class name="Cust" />
<inheritance:implements>jaxb.BaseMessage</inheritance:implements>
</jaxb:bindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="schema/y.xsd">
<jaxb:bindings node="//xsd:complexType[@name='Payments']">
<jaxb:class />
<inheritance:implements>jaxb.BaseMessage</inheritance:implements>
</jaxb:bindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="schema/common.xsd">
<jaxb:bindings node="//xsd:complexType[@name='CustomerPayments']">
<jaxb:class />
<inheritance:implements>jaxb.BaseMessage</inheritance:implements>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
src/main/resources/schema/common.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:x="http://test.org/common/x"
xmlns:y="http://test.org/common/y"
targetNamespace="http://test.org/common">
<xsd:import namespace="http://test.org/common/x" schemaLocation="x.xsd" />
<xsd:import namespace="http://test.org/common/y" schemaLocation="y.xsd" />
<xsd:complexType name="CustomerPayments">
<xsd:sequence>
<xsd:element name="customer" type="x:Customer" />
<xsd:element name="payments" type="y:Payments" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
src/main/resources/schema/x.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
targetNamespace="http://test.org/common/x">
<xsd:complexType name="Customer">
<xsd:sequence>
<xsd:element name="name" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
src/main/resources/schema/y.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
targetNamespace="http://test.org/common/y">
<xsd:complexType name="Payments">
<xsd:sequence>
<xsd:element name="amount" type="xsd:float" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
build.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE project>
<project name="JAXB XPath Test" default="xjc" basedir=".">
<property name="build.folder" location="build" />
<taskdef name="xjc" classname="org.jvnet.jaxb2_commons.xjc.XJC2Task">
<classpath>
<fileset dir="${basedir}/lib">
<include name="jaxb-impl-2.2.6.jar" />
<include name="jaxb-xjc-2.2.6.jar" />
<include name="jaxb2-basics-ant-0.9.4.jar" />
<include name="javaparser-1.0.11.jar" />
<include name="commons-lang3-3.2.jar" />
</fileset>
</classpath>
</taskdef>
<target name="xjc" description="Generate the source code.">
<xjc destdir="${basedir}/src/main/java" extension="true">
<arg line="
-Xequals
-XhashCode
-XtoString
-Xcopyable
-Xmergeable
-Xinheritance" />
<binding dir="${basedir}/src/main/resources">
<include name="**/*.xjb" />
</binding>
<schema dir="${basedir}/src/main/resources/schema">
<include name="**/*.xsd" />
</schema>
<classpath>
<fileset dir="${basedir}/lib">
<include name="jaxb2-basics-0.9.4.jar"/>
<include name="jaxb2-basics-runtime-0.9.4.jar"/>
<include name="jaxb2-basics-tools-0.9.4.jar"/>
<include name="commons-beanutils-1.8.0.jar"/>
<include name="commons-lang3-3.2.jar"/>
<include name="commons-logging-1.1.1.jar"/>
</fileset>
</classpath>
</xjc>
</target>
</project>