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

发布于 2024-11-20 00:23:35 字数 2240 浏览 3 评论 0原文

我有几十个 .xsd 文件,我想为其自动生成代码。当我尝试同时生成所有文件时,有几个文件具有重复的名称,这些名称会发生​​冲突。

我专注于让其中两个发挥作用。

当我让这两个工作正常时,我会修复其余的。但我现在只关注其中的两个文件。我无法控制它们,它们来自供应商并遵循“标准”,因此出于多种原因编辑它们不是一个选项

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

我按照 mat b 的答案和我在网上找到的其他说明中的链接中的建议添加了一个 binding.xjb 文件。但我收到以下错误,没有输出。

<?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 文件之前开始的地方,只需在 pom.xml 中指定 package 即可。

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

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 them at the same time.

I am focusing on just trying to get 2 of these to work.

When I get these 2 working I will fix the rest. But I am just focusing on 2 of these files for now. I am not in control of them, they are from a vendor and follow a "standard", so editing them is not an option for multiple reasons.

I am using the maven-jaxb2-plugin to process these files.

I added a binding.xjb file as suggested in the link in mat b's answer and other instructions I have found on the web. But I am getting the following errors, an no output.

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

gives the following error

[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

The offending element is : ( there are many others this is just the first one that clashes )

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

And is identical in each of the .xsd files, how do I resolve this duplication with either only one class being generated or each one being generated in to their own package namespace?

This isn't the only duplicate element like this there are lots of them, so just trying to remove them from the files isn't a option either.

This halign is in multiple .xsd files and I want to either put them in their individual packages, or be able to tell the compiler to use the first one that was generated.

This is where I started off before I tried an external .xjb file, by just specifying the package in the pom.xml.

How do I configure the binding to either ignore the duplicate configurations, map them to separate packages or map them to existing implementations?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

居里长安 2024-11-27 00:23:35

我有一个半途而废的解决方案,但它非常耗时。
我必须为每个具有重复条目的文件创建一个单独的

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

true很重要,否则只有第一个会运行,其余的会认为不需要运行因为我生成到同一个目录中。

我仍然希望有一个劳动强度较低的解决方案来处理重复项。

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

从那时起,我决定尽可能放弃 XML,并完全放弃 JAXB。自本次编辑以来,有更新更好的方法来解析 XML 并将其映射到对象。

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.

ヤ经典坏疍 2024-11-27 00:23:35

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

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.

岁吢 2024-11-27 00:23:35

我发布了 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
}

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
}
夜血缘 2024-11-27 00:23:35

元素添加到 XSD:

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

Add a <schemaBindings> element to the XSD:

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

Source

灼疼热情 2024-11-27 00:23:35

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

我们可以通过添加 exclude 标签在 ma​​ven 插件配置(在 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>

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>
熊抱啵儿 2024-11-27 00:23:35

2.5.0 的实际解决方案:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>${jaxb2-maven-plugin.version}</version>
    <executions>
        <execution>
            <id>base</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>xjc</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/main/resources/some.xsd</source>
                </sources>
                <packageName>com.my.example.one</packageName>
                <clearOutputDir>false</clearOutputDir>
            </configuration>
        </execution>
        <execution>
            <id>ceph</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>xjc</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/main/resources/some2.xsd</source>
                </sources>
                <packageName>com.my.example.two</packageName>
                <clearOutputDir>false</clearOutputDir>
            </configuration>
        </execution>
    </executions>
</plugin>

您需要为不同的 xsd 创建一些不同的包,并且应该在每个

官方文档中使用 false:https://www.mojohaus.org/jaxb2-maven-plugin/Documentation/v2.2/faq.html#Multiple

Actual solution for 2.5.0:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>${jaxb2-maven-plugin.version}</version>
    <executions>
        <execution>
            <id>base</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>xjc</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/main/resources/some.xsd</source>
                </sources>
                <packageName>com.my.example.one</packageName>
                <clearOutputDir>false</clearOutputDir>
            </configuration>
        </execution>
        <execution>
            <id>ceph</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>xjc</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/main/resources/some2.xsd</source>
                </sources>
                <packageName>com.my.example.two</packageName>
                <clearOutputDir>false</clearOutputDir>
            </configuration>
        </execution>
    </executions>
</plugin>

You need create some with different packages for different xsd AND you should use false in every

Official doc: https://www.mojohaus.org/jaxb2-maven-plugin/Documentation/v2.2/faq.html#Multiple

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文