Is there a way to deal with duplicate element definitions across multiple .xsd files in JAXB?

后端 未结 5 1974
予麋鹿
予麋鹿 2020-12-05 05:35

I have dozens and dozens .xsd files that I want to auto-generate code for. A couple of the files have duplicate names that clash when I try to generate all of t

相关标签:
5条回答
  • 2020-12-05 05:38

    I have a half-way workaround solution to this, but it is very time intensive. I had to create a separate <execution/> for every one of the files that has duplicate entries.

    <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>
    

    The <forceRegenerate>true</forceRegenerate> is important or only the first <execution/> will run and the rest will think that there is no need to run because I am generating into the same directory.

    I would still like a less labor intensive solution to deal with the duplicates.

    I think if I make the first master .xsd a separate module that builds into its own .jar file, I could then use the <episode/> tag and have it skip generating the same duplicate elements over and over, since they are identical in definition.

    I have since decided to abandon XML if at all possible and JAXB completely. There are newer and better ways to parse XML and map it to objects as of this edit.

    0 讨论(0)
  • 2020-12-05 05:40

    Realize this is old, but I had the same error and could it resolve it by not specifying a target package, i.e. the -b option with xjc. Then the duplicate elements each get created in their own namespace package and no conflict.

    0 讨论(0)
  • 2020-12-05 05:57

    Add a <schemaBindings> element to the XSD:

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

    Source

    0 讨论(0)
  • 2020-12-05 06:02

    We had a similar problem: we had one wsdl file and two xsd files in the same directory. The wsdl file imports the two xsd files. The problem was that JAXB was taking all three files into consideration and throwing '... is already defined' error. It was basically complaining that it saw the same element in both wsdl and xsd file.

    We could fix this issue in the maven plugin configuration (in pom.xml) by adding an exclude tag as in the following example:

        <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>
    
    0 讨论(0)
  • 2020-12-05 06:03

    I post my solution for gradle, it solves duplicate issue and does`not require xjb files:

    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
    }
    
    0 讨论(0)
提交回复
热议问题