当两个单独的模式具有相同的命名空间时,如何告诉JAXB在单独的包中生成类?

时间:2016-07-26 14:36:41

标签: java xml xsd namespaces jaxb

我怀疑对此没有好的答案,但希望我能错过一些东西。假设我有两个独立的XML模式,它们都具有相同的命名空间,定义了一些重复的complexTypes,我想用JAXB为它们生成Java类。作为一个非常简单的例子:

schema1.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" targetNamespace="namespace1" xmlns="namespace1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="foo" type="xs:string"/>
</xs:schema>

schema2.xsd:(与上述相同)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" targetNamespace="namespace1" xmlns="namespace1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="foo" type="xs:string"/>
</xs:schema>

当我尝试使用JAXB(通过gradle的Ant XJC任务)生成这些时,我得到以下,完全合理的错误:

[ant:xjc] [ERROR] 'foo' is already defined
[ant:xjc]   line 3 of file:/C:/dev/test/src/main/resources/schema2.xsd
[ant:xjc]
[ant:xjc] [ERROR] (related to above error) the first definition appears here
[ant:xjc]   line 3 of file:/C:/dev/test/src/main/resources/schema1.xsd

根据JAXB docs,我尝试在外部自定义文件中指定包,如下所示:

<jaxb:bindings schemaLocation="schema1.xsd">
    <jaxb:schemaBindings>
        <jaxb:package name="package1"/>
    </jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="schema2.xsd">
    <jaxb:schemaBindings>
        <jaxb:package name="package2"/>
    </jaxb:schemaBindings>
</jaxb:bindings>

但这不起作用 - 然后我意识到上面链接的相同文档说:

  

请注意,此自定义是每个命名空间。也就是说,即使您的模式被拆分为多个模式文档,如果它们都在同一名称空间中,也不能将它们放入不同的包中。

所以,我猜测它永远不会起作用。

这有什么明智的方法吗?我怀疑正确的答案是模式应该在不同的名称空间中,因为这可以解决问题,并且可能更具逻辑意义,但我不能控制模式 - 它们由第三方提供。我问过是否有可能改变它们,但我怀疑答案是否定的。

我能看到的唯一另一个选项是两次生成Java类,首先是schema1.xsd,然后是schema2.xsd,每次都有自己的自定义文件指定不同的包,但感觉就像一个笨拙的解决方案。我有什么更明智的选择吗?

1 个答案:

答案 0 :(得分:2)

你做不到。包是基于名称空间生成的。相同的命名空间 - 相同的包。

在这种情况下,您必须执行多次执行。还要注意使用不同的输出生成目录(如target/generated-sources/xjc1target/generated-sources/xjc2),否则“仅在发生任何更改时编译”将无法正常工作。