SAXParseException:“< element>”已定义:如何使用JAXB2 Maven插件从冲突XSD定义生成Java代码?

h9a6wy2h  于 2023-04-10  发布在  Java
关注(0)|答案(1)|浏览(149)

我有两个无法控制的XSD文档-也就是说,我不能强迫它们的作者更改它们。不幸的是,当并排使用XSDs时,它们是无效的,因为它们包含冲突的定义:

<!-- first.xsd -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:onl="http://example/data/online" xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="http://example/data/online" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.4">
    <xs:element name="content">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="docSeqId" type="xs:long">
                    <xs:annotation>
                        <xs:documentation>Identifier of a documentation sequence.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="customerName" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>Name of a customer.</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

<!-- second.xsd -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:onl="http://example/data/online" xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="http://example/data/online" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.4">
    <xs:element name="content">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="transactionId" type="xs:long">
                    <xs:annotation>
                        <xs:documentation>Id of a transaction.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="amount" type="xs:decimal">
                    <xs:annotation>
                        <xs:documentation>Transaction amount.</xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="targetAccountId" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>Id (GUID) of a target account.</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

我创建了以下jaxb2-maven-plugin配置:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <outputDirectory>${project.build.directory}/generated-sources/</outputDirectory>
    </configuration>
    <executions>
        <execution>
            <id>generate-source-code</id>
            <goals>
                <goal>xjc</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/main/resources/integration/first.xsd</source>
                    <source>src/main/resources/integration/second.xsd</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

但是当我执行相关的maven阶段时,构建退出,并出现以下错误:
[错误]文件:/C:/Users/Andy/development/sample-project/src/main/resources/integration/second.xsd [23,18] org.xml.sax.SAXParseException:'content'已定义
如何从XSD文件生成有效的Java代码,以便使用它们?

whlutmcx

whlutmcx1#

我发现我面临着两个问题:
1.生成将导致相同的类,即我将在同一个包中重复定义Content类-这显然不起作用,
1.冲突的XSD文件,这将不允许jaxb2-maven-plugin同时处理它们。
为了解决两个问题中的第一个,我使用了两个.xjb(XML到Java的绑定文件,每个文件对应一个无效的.xsd),其中我定义了来自给定.xsd的源代码应该放在哪个Java包中。
绑定文件如下所示:

<!-- first.xjb -->
<jxb:bindings version="3.0"
              xmlns:jxb="https://jakarta.ee/xml/ns/jaxb"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <jxb:bindings schemaLocation="../integration/first.xsd" node="//xsd:schema">
        <jxb:schemaBindings>
            <jxb:package name="example.data.online.first"/>
        </jxb:schemaBindings>
    </jxb:bindings>
</jxb:bindings>

<!-- second.xjb -->
<jxb:bindings version="3.0"
              xmlns:jxb="https://jakarta.ee/xml/ns/jaxb"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <jxb:bindings schemaLocation="../integration/second.xsd" node="//xsd:schema">
        <jxb:schemaBindings>
            <jxb:package name="example.data.online.second"/>
        </jxb:schemaBindings>
    </jxb:bindings>
</jxb:bindings>

通过使用绑定(以及其他方法),我能够覆盖目标Java包。
我通过创建jaxb2-maven-plugin的两个单独的执行来解决第二个问题,每个.xsd都有一个冲突,每个冲突都使用了相关的.jxb绑定文件。

**重要提示:**默认情况下,jaxb2-maven-plugin在每次生成执行前都会清空输出目录。我的例子是想合并生成的代码,可以通过将clearOutputDir参数设置为false来完成。

插件的最终配置如下所示:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <outputDirectory>${project.build.directory}/generated-sources/</outputDirectory>
        <clearOutputDir>false</clearOutputDir>
    </configuration>
    <executions>
        <execution>
            <id>first-generator</id>
            <goals>
                <goal>xjc</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/main/resources/integration/first.xsd</source>
                </sources>
                <xjbSources>
                    <xjbSource>src/main/resources/jaxb2/first.xjb</xjbSource>
                </xjbSources>
            </configuration>
        </execution>
        <execution>
            <id>second-generator</id>
            <goals>
                <goal>xjc</goal>
            </goals>
            <configuration>
                <sources>
                    <source>src/main/resources/integration/second.xsd</source>
                </sources>
                <xjbSources>
                    <xjbSource>src/main/resources/jaxb2/second.xjb</xjbSource>
                </xjbSources>
            </configuration>
        </execution>
    </executions>
</plugin>

导致正确的Java代码生成:

相关问题