JAXB:为共享一个公共 XSD 的两个 XSD 生成类

2022-09-03 02:41:27

我有2个服务XSD文件AService.xsd和BService.xsd,每个文件都有不同的目标命名空间。这两者都使用称为common.xsd的通用XSD。我使用JAXB Maven插件来生成类。操作方法如下:

<execution>
    <id>generate-package</id>
    <goals>
        <goal>generate</goal>
    </goals>
    <configuration>
        <extension>true</extension>
        <schemaIncludes>
            <include>schema/Aservice.xsd</include>
            <include>schema/Bservice.xsd</include>                             
        </schemaIncludes>
        <bindingIncludes>                                   
            <include>schema/*.xjb</include>
        </bindingIncludes>
        <generatePackage>com.schema</generatePackage>
        <generateDirectory>src/main/java</generateDirectory>
    </configuration>
</execution>

当我尝试运行这个时,我得到以下错误。 在 common.xsd 中定义ValidationType

org.xml.sax.SAXParseException: A class/interface with the same name "com.schema.ValidationType" is already in use. Use a class customization to resolve this conflict.
..........
org.xml.sax.SAXParseException: (Relevant to above error) another "ValidationType" is generated from here.
......
com.sun.istack.SAXParseException2: Two declarations cause a collision in the ObjectFactory class.

如果我在2个不同的执行中运行2个服务xsds,生成到2个不同的包中,我在2个不同的包中得到相同的类。ValidationType

关于如何使 JAXB 识别共享模式的任何想法?


答案 1

你正面临着一个所谓的“变色龙模式”,这被认为是一种不好的做法。不幸的是,由于JAXB的性质,没有好的解决方案。JAXB 注解将 Bean 属性绑定到特定名称空间中的 XML 元素和属性(在模式编译时确定)。因此,一旦编译了架构,就没有官方的好方法来更改属性绑定到的元素和属性的命名空间。

但是,这正是您希望通过“变色龙”模式实现的目标。从“common.xsd”派生的类应该以某种方式神奇地映射到命名空间A(如果在A类中使用)和命名空间B(如果在B类中使用)。我可以想象这种魔力,但在现实生活中从未见过。

由于您基本上希望A /common和B / common是“同一件事”,因此解决它的方法之一是在两次执行中生成A和B(都具有公共),并使公共类实现某个“通用”接口。然后,您的软件可以在同一 faschion 中处理 A/common 和 B/common,而不管这些实际上是来自不同软件包的类。

更新:

从评论中我看到你没有变色龙模式,而只是一个正常的导入。这很容易,只需分别编译普通,A和B。请参阅 maven-jaxb2-plugin 的单独架构编译


答案 2

我自定义了此处描述的软件包。因此,进入并由它们共享,并且它们都位于不同的包本身中,因为它们位于不同的命名空间中。common.xsdcom.common.schemaAService.xsdBService.xsd

已从 maven 配置中删除,如下所示,generatePackage

<execution>
    <id>generate-package</id>
    <goals>
        <goal>generate</goal>
    </goals>
    <configuration>
        <extension>true</extension>
        <schemaIncludes>
            <include>schema/Aservice.xsd</include>
            <include>schema/Bservice.xsd</include>                            
        </schemaIncludes>
        <bindingIncludes>
            <include>schema/*.xjb</include>
        </bindingIncludes>                                
        <generateDirectory>src/main/java</generateDirectory>
    </configuration>
</execution>

推荐