有没有办法在JAXB中处理多个.xsd文件中的重复元素定义?

时间:2011-07-13 15:18:48

标签: java maven jaxb maven-plugin maven-jaxb2-plugin

我有几十个.xsd个文件,我想自动生成代码。当我尝试同时生成所有文件时,一些文件具有重复的名称。

我专注于尝试让其中的两个工作。

当我得到这两个工作时,我会解决剩下的问题。但我现在只关注其中的两个文件。我无法控制它们,它们来自供应商并遵循“标准”,因此编辑它们不是一个选项,原因有多种。

我正在使用maven-jaxb2-plugin来处理这些文件。

我根据binding.xjb的回答中的链接以及我在网络上找到的其他说明添加了mat b文件。但我得到以下错误,没有输出。

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="2.1"
              xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
              xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xsi:schemaLocation=" http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd">
  <jxb:bindings schemaLocation="mac-3.4.xsd">
    <jxb:schemaBindings>
      <jxb:package name="my.company.mac"/>
    </jxb:schemaBindings>
  </jxb:bindings>
  <jxb:bindings schemaLocation="mac-stylesheet-3.4.xsd">
    <jxb:schemaBindings>
      <jxb:package name="my.company.stylesheet"/>
    </jxb:schemaBindings>
  </jxb:bindings>
</jxb:bindings>

给出以下错误

[ERROR] Error while parsing schema(s).Location [ file:/C:/Users/Jarrod%20Roberson/Projects/spa-tools/spa-lib/src/main/sc
hema/mac-stylesheet-3.4.xsd{165,33}].
org.xml.sax.SAXParseException: 'halign' is already defined

违规元素是:(还有很多其他元素,这只是第一个发生冲突的元素)

<xsd:simpleType name="halign">
  <xsd:restriction base="xsd:string">
    <xsd:enumeration value="left" />
    <xsd:enumeration value="center" />
    <xsd:enumeration value="right" />
  </xsd:restriction>
</xsd:simpleType>

并且在每个.xsd文件中都是相同的,如何使用仅生成一个类或者将每个类生成到其自己的包名称空间中来解决此重复问题?

这不是唯一一个像这样的重复元素,它们有很多,所以只是尝试从文件中删除它们也不是一种选择。

这个halign在多个.xsd文件中,我想要将它们放在各自的包中,或者能够告诉编译器使用第一个生成的文件。

这是我在尝试外部.xjb文件之前开始的地方,只需在package中指定pom.xml

如何配置绑定以忽略重复配置,将它们映射到单独的包或将它们映射到现有实现?

5 个答案:

答案 0 :(得分:11)

我有一个解决此问题的中途解决方案,但这是非常耗费时间的。 我必须为每个有重复条目的文件创建一个单独的<execution/>

<executions>
  <execution>
    <id>jaxb-mac</id>
    <phase>generate-sources</phase>
    <goals>
      <goal>generate</goal>
    </goals>
    <configuration>
      <forceRegenerate>true</forceRegenerate>
      <generatePackage>my.company.mac</generatePackage>
      <schemaDirectory>src/main/schema</schemaDirectory>
      <schemaIncludes>
        <include>mac-3.4.xsd</include>
      </schemaIncludes>
    </configuration>
  </execution>
  <execution>
    <id>jaxb-stylesheet</id>
    <phase>generate-sources</phase>
    <goals>
      <goal>generate</goal>
    </goals>
    <configuration>
      <forceRegenerate>true</forceRegenerate>
      <generatePackage>my.company.stylesheet</generatePackage>
      <schemaDirectory>src/main/schema</schemaDirectory>
      <schemaIncludes>
        <include>mac-stylesheet-3.4.xsd</include>
      </schemaIncludes>
    </configuration>
  </execution>

<forceRegenerate>true</forceRegenerate>很重要,或只有第一个<execution/>会运行,其余人会认为无需运行,因为我正在生成同一个目录。

我仍然希望用较少的劳动密集型解决方案来处理重复项。

我认为如果我将第一个主.xsd构建为一个单独的模块,构建到自己的.jar文件中,那么我可以使用<episode/>标记并让它跳过一遍又一遍地生成相同的重复元素,因为它们的定义相同。

我已经决定尽可能放弃XML并完全放弃JAXB。在编辑时,有更新更好的方法来解析XML并将其映射到对象。

答案 1 :(得分:3)

意识到这是旧的,但我有同样的错误,可以通过不指定目标包来解决它,即使用xjc的-b选项。然后,每个重复元素都在自己的命名空间包中创建,没有冲突。

答案 2 :(得分:1)

向XSD添加<schemaBindings>元素:

<schemaBindings>
    <package name="com.whatever.stuff" />
</schemaBindings>

Source

答案 3 :(得分:0)

我发布了 gradle 的解决方案,它解决了重复的问题并且不需要xjb文件:

task generateJaxb() {
    ext.sourcesDir = "${buildDir}/generated-sources/jaxb"
    ext.classesDir = "${buildDir}/classes/jaxb"
    ext.schemaDir = "src/resources/schemas"
    ext.tmp = "${buildDir}/tmp/xjc"

    doLast() {
        project.ant {
            taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
                    classpath: configurations.jaxb.asPath

            delete(dir: tmp)
            mkdir(dir: tmp)
            delete(dir: sourcesDir)
            delete(dir: classesDir)
            mkdir(dir: sourcesDir)
            mkdir(dir: classesDir)
        }

        fileTree(schemaDir){
            include '**/*.xsd'
            include '**/*.wsdl'
        }.each{File file->
            //println file
            project.ant {
                taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
                        classpath: configurations.jaxb.asPath
                xjc(destdir: tmp, schema:"${file.getAbsolutePath()}") {
                    arg(value: "-wsdl")
                    produces(dir: tmp, includes: "**/*.java")
                }
                copy(todir: sourcesDir) {
                    fileset(dir: tmp, erroronmissingdir: false) {
                        include(name: "**/*.java")
                    }
                }
                delete(dir: tmp)
                mkdir(dir: tmp)
            }
        }
        project.ant {
            javac(destdir: classesDir, source: 1.6, target: 1.6, debug: true,
                    debugLevel: "lines,vars,source",
                    classpath: configurations.jaxb.asPath) {
                src(path: sourcesDir)
                include(name: "**/*.java")
                include(name: "*.java")
            }

            copy(todir: classesDir) {
                fileset(dir: sourcesDir, erroronmissingdir: false) {
                    exclude(name: "**/*.java")
                }
            }
        }
    }
}

configurations {
    jaxb
}

dependencies {
    jaxb("com.sun.xml.bind:jaxb-xjc:2.2.4-1")
    compile(files(generateJaxb.classesDir).builtBy(generateJaxb))
}

jar {
    from generateJaxb.classesDir
}

答案 4 :(得分:0)

我们遇到了类似的问题:我们在同一目录中有一个wsdl文件和两个xsd文件。 wsdl文件导入两个xsd文件。问题在于JAXB正在考虑所有三个文件并且已经定义了抛出&#39; ...错误。它基本上抱怨它在wsdl和xsd文件中都看到了相同的元素。

我们可以通过添加排除标记在 maven插件配置(在pom.xml中)中修复此问题,如下例所示:

    <build>
    <plugins>
        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.12.3</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <schemaLanguage>WSDL</schemaLanguage>
                <generatePackage>mywsdl.wsdl</generatePackage>
                <args><arg>-XautoNameResolution</arg></args>
                <schemas>
                    <schema>
                        <fileset>
                            <excludes>
                                <exclude>*.xsd</exclude>
                            </excludes>
                        </fileset>
                    </schema>
                </schemas>
            </configuration>
        </plugin>
    </plugins>
</build>