webdevqa.jp.net

JAXBの複数の.xsdファイル間で重複する要素定義を処理する方法はありますか?

コードを自動生成したい.xsdファイルが数十個あります。いくつかのファイルの名前が重複しているため、すべてを同時に生成しようとすると衝突します。

私はこれらのうちの2つを機能させることに集中しています。

これら2つが機能するようになったら、残りを修正します。しかし、私は今のところこれらのファイルのうちの2つに焦点を合わせています。私はそれらを管理していません、それらはベンダーからのものであり、 "標準"に従うので、それらを編集することはオプションではありません複数の理由で。

私はこれらのファイルを処理するためにmaven-jaxb2-pluginを使用しています。

binding.xjbの回答のリンクや、Webで見つけたその他の手順で提案されているように、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ファイルで同一ですが、1つのクラスのみが生成されるか、各クラスが独自のパッケージ名前空間に生成されることで、この重複を解決するにはどうすればよいですか?

このような重複する要素はこれだけではありません。それらはたくさんあるので、ファイルからそれらを削除しようとすることも選択肢ではありません。

このhalignは複数の.xsdファイルにあり、それらを個別のパッケージに入れるか、最初に生成されたファイルを使用するようにコンパイラーに指示できるようにします。

これは、外部の.xjbファイルを試す前に、pom.xmlpackageを指定するだけで始めたところです。

重複する構成を無視するか、個別のパッケージにマップするか、既存の実装にマップするようにバインディングを構成するにはどうすればよいですか?

23
user177800

これに対する中途半端な回避策がありますが、非常に時間がかかります。エントリが重複しているファイルごとに個別の<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を解析し、オブジェクトにマップするためのより新しく、より良い方法があります。

11
user177800

これは古いことに気づきましたが、同じエラーが発生し、ターゲットパッケージを指定しない、つまりxjcで-bオプションを使用して解決できました。次に、重複する要素はそれぞれ独自の名前空間パッケージに作成され、競合は発生しません。

3
mrcrabs

XSDに<schemaBindings>要素を追加します。

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

ソース

1
matt b

同様の問題がありました。同じディレクトリに1つのwsdlファイルと2つのxsdファイルがありました。 wsdlファイルは2つのxsdファイルをインポートします。問題は、JAXBが3つのファイルすべてを考慮に入れており、「...はすでに定義されています」というエラーをスローすることでした。基本的に、wsdlファイルとxsdファイルの両方に同じ要素が含まれていると不平を言っていました。

次の例のようにexcludeタグを追加することで、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>
0
caytekin

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
}
0
pgregory