【问题标题】:How to generate java classes from multiple xsd with common schema using maven如何使用 maven 从具有通用模式的多个 xsd 生成 java 类
【发布时间】:2018-10-24 03:34:22
【问题描述】:

我正在尝试从多个 xsd 文件生成 java 类。 但是我得到了这个错误。

org.xml.sax.SAXParseException; ... 'someelement' 已经定义了

我认为这是由于多次包含的常见类型。

如何使用 maven 生成 java 类?

我在一个目录中有以下架构:

xsd:

  • EXAMPLE_QualifyRS.xsd
  • EXAMPLE_QualifyRQ.xsd
  • EXAMPLE_Peble_CommonTypes.xsd
  • EXAMPLE_CommonTypes.xsd
  • EXAMPLE_SimpleTypes.xsd

EXAMPLE_QualifyRS.xsd

<xs:schema xmlns="http://www.example.org/EXAMPLE/2007/00" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/EXAMPLE/2007/00" elementFormDefault="qualified" version="1.002" id="EXAMPLE2016.1">
    <xs:include schemaLocation="EXAMPLE_CommonTypes.xsd"/>
    <xs:include schemaLocation="EXAMPLE_SimpleTypes.xsd"/>
    <xs:include schemaLocation="EXAMPLE_Peble_CommonTypes.xsd"/>
         <xs:element name="someelement">...</xs:element>

EXAMPLE_Peble_CommonTypes.xsd

<xs:schema xmlns="http://www.example.org/EXAMPLE/2007/00" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/EXAMPLE/2007/00" elementFormDefault="qualified" version="1.000" id="EXAMPLE2016.1">
    <xs:include schemaLocation="EXAMPLE_CommonTypes.xsd"/>

EXAMPLE_QualifyRQ.xsd

<xs:schema xmlns="http://www.example.org/EXAMPLE/2007/00" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/EXAMPLE/2007/00" elementFormDefault="qualified" version="1.001" id="EXAMPLE2016.1">
    <xs:include schemaLocation="EXAMPLE_CommonTypes.xsd"/>
    <xs:include schemaLocation="EXAMPLE_SimpleTypes.xsd"/>
    <xs:include schemaLocation="EXAMPLE_Peble_CommonTypes.xsd"/>
        <xs:element name="someelement">...</xs:element>

这就是我如何在 maven 中生成我的类

<plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jaxb2-maven-plugin</artifactId>
                <version>2.4</version>
                <executions>
                    <execution>
                        <id>example-schema</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>xjc</goal>
                        </goals>
                        <configuration>
                            <xsdPathWithinArtifact>xsd</xsdPathWithinArtifact>
                            <addGeneratedAnnotation>true</addGeneratedAnnotation>
                            <laxSchemaValidation>true</laxSchemaValidation>
                            <laxSchemaValidation>true</laxSchemaValidation>
                            <readOnly>true</readOnly>
                            <verbose>true</verbose>
                            <sources>
                                <source>src/main/resources/xsd</source>
                            </sources>
                            <packageName>com.example</packageName>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

【问题讨论】:

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


    【解决方案1】:

    假设您的 common.xsd 中有一个“Person”,如下例所示:

    <xs:schema xmlns="common.schema.def"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               targetNamespace="common.schema.def"
               elementFormDefault="qualified">
    
        <xs:complexType name="Person">
            <xs:sequence>
                    <xs:element name="name" type="xs:string"/>
                    <xs:element name="age" type="xs:int"/>
            </xs:sequence>
        </xs:complexType>
    </xs:schema>
    

    并且您想在另一个架构中使用它。然后你会这样做:

    <xs:schema xmlns="http://www.example.org/EXAMPLE/2007/00"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:common="common.schema.def"
               targetNamespace="http://www.example.org/EXAMPLE/2007/00"
               elementFormDefault="qualified">
        <xs:import namespace="common.schema.def" schemaLocation="common.xsd"/>
    
        <xs:complexType name="someClass">
            <xs:sequence>
                <xs:element name="person" type="common:Person"/>
                <xs:element name="alias" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:schema>
    

    编辑以回复评论:

    发生名称冲突是因为您在插件中指定了包名称。然后尝试将具有相同名称的类放在同一个包下。让我们从插件中删除包命名,并使用绑定为每个模式创建所需的包。

    您的插件将如下所示:

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>jaxb2-maven-plugin</artifactId>
        <version>2.4</version>
        <executions>
            <execution>
                <id>example-schema</id>
                <phase>generate-sources</phase>
                <goals>
                    <goal>xjc</goal>
                </goals>
                <configuration>
                    <xsdPathWithinArtifact>xsd</xsdPathWithinArtifact>
                    <addGeneratedAnnotation>true</addGeneratedAnnotation>
                    <laxSchemaValidation>true</laxSchemaValidation>
                    <laxSchemaValidation>true</laxSchemaValidation>
                    <readOnly>true</readOnly>
                    <verbose>true</verbose>
                    <sources>
                        <source>src/main/resources/xsd</source>
                    </sources>
                    <xjbSources>
                        <xjbSource>src/main/resources/xjb</xjbSource>
                    </xjbSources>
                </configuration>
            </execution>
        </executions>
    </plugin>
    

    bindings.xjb 看起来像这样:

    <jxb:bindings version="1.0"
                  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <jxb:bindings schemaLocation="../xsd/common.xsd">
            <jxb:schemaBindings>
                <jxb:package name="common.packagename"/>
            </jxb:schemaBindings>
        </jxb:bindings>
        <jxb:bindings schemaLocation="../xsd/someothercommon.xsd">
            <jxb:schemaBindings>
                <jxb:package name="othercommon.packagename"/>
            </jxb:schemaBindings>
        </jxb:bindings>
    </jxb:bindings>
    

    为了测试它,我使用了另一个 xsd,其中包含一个名为 Person 的元素,如下所示:

    <xs:schema xmlns="othercommon.schema.def"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               targetNamespace="othercommon.schema.def"
               elementFormDefault="qualified">
    
        <xs:complexType name="Person">
            <xs:sequence>
                <xs:element name="alias" type="xs:string"/>
                <xs:element name="id" type="xs:int"/>
            </xs:sequence>
        </xs:complexType>
    </xs:schema>
    

    同时使用两者的架构更新为:

    <xs:schema xmlns="http://www.example.org/EXAMPLE/2007/00"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:common="common.schema.def"
               xmlns:othercommon="othercommon.schema.def"
               targetNamespace="http://www.example.org/EXAMPLE/2007/00"
               elementFormDefault="qualified">
        <xs:import namespace="common.schema.def" schemaLocation="common.xsd"/>
        <xs:import namespace="othercommon.schema.def" schemaLocation="someothercommon.xsd"/>
    
        <xs:complexType name="someClass">
            <xs:sequence>
                <xs:element name="person" type="common:Person"/>
                <xs:element name="otherpersontype" type="othercommon:Person"/>
            </xs:sequence>
        </xs:complexType>
    </xs:schema>
    

    【讨论】:

    • 不幸的是,我无法更改架构。因为这个架构来自另一个国际组织。有没有办法从这些模式生成 java 类?
    • @user311633 不同元素的元素名称是否相同?
    • 没错,就是不同schema中不同元素的同一个元素名。如果必须,我也不介意使用其他插件。
    • @user311633 编辑答案以解决您的姓名冲突问题
    猜你喜欢
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-27
    相关资源
    最近更新 更多