Search code examples
javaxmlxsdjaxbjaxb2-maven-plugin

JAXB XJC: how to resolve XSD to Java property conflicts?


I'm trying to generate Java classes starting from an XML Schema Definition but I'm getting an error about a Property "Lang" is already defined.

[ERROR] http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd [302,52] 
com.sun.istack.SAXParseException2: Property "Lang" is already defined. Use <jaxb:property> to resolve this conflict.

[ERROR] http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd [303,35] 
com.sun.istack.SAXParseException2

The XSD I'm using defines the Common Weakness Enumeration (CWE) and is located at https://cwe.mitre.org/data/xsd/cwe_schema_v6.10.xsd

A short command to reproduce the error is:

xjc http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd

This is my pom.xml

<build>
    <plugins>
        <!-- https://www.mojohaus.org/jaxb2-maven-plugin/#/repo -->
        <!-- https://www.mojohaus.org/jaxb2-maven-plugin/Documentation/v3.1.0/index.html -->
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <sources>
                    <source>_schema_/cwe</source>
                </sources>
                <xjbSources>
                    <xjbSource>${basedir}/cti-domain/src/main/xjb</xjbSource>
                </xjbSources>
                <outputDirectory>${basedir}/cti-domain/src/main/java</outputDirectory>
                <clearOutputDir>false</clearOutputDir>
            </configuration>
            <executions>
                <execution>
                    <id>xjc</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

and this is my attempt to fix the error:

<!-- cti-domain/src/main/xjb/cwe-bindings.xjb -->

<jxb:bindings version="1.0"
              xmlns:jxb="https://jakarta.ee/xml/ns/jaxb"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <jxb:bindings schemaLocation="../../../../_schema_/cwe/cwe_schema_v6.10.xsd" node="//xsd:schema">
        <jxb:schemaBindings>
            <jxb:package name="com.example.cwe"/>
        </jxb:schemaBindings>

<!--        <jxb:bindings schemaLocation="http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd" node="//xsd:schema">-->
<!--            <jxb:property name="Language"/>-->
<!--        </jxb:bindings>-->
    </jxb:bindings>
</jxb:bindings>

Solution

  • You need to rename the 'lang' property at line 302 & line 1166 in http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd to something that does not clash, eg 'langAttribute'

    The first 'lang' is in the last line in the snippet of xhtml1-strict.xsd below:

      <xs:element name="bdo">
        <xs:annotation>
          <xs:documentation>
          I18N BiDi over-ride
          </xs:documentation>
        </xs:annotation>
        <xs:complexType mixed="true">
          <xs:complexContent>
            <xs:extension base="Inline">
              <xs:attributeGroup ref="coreattrs"/>
              <xs:attributeGroup ref="events"/>
              <xs:attribute name="lang" type="LanguageCode"/>
    

    This is what should be in the xjb file:

    <!-- cti-domain/src/main/xjb/cwe-bindings.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="http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd" node="//xsd:schema">
            <jxb:schemaBindings>
                <jxb:package name="com.example.cwe"/>
            </jxb:schemaBindings>
    
            <!-- rename the 'lang' attribute on line 302 to 'langAttribute' -->
            <jxb:bindings node="//xsd:attributeGroup[@name='i18n']/xsd:attribute[@name='lang']">
                <jxb:property name="langAttribute"/>
           </jxb:bindings>
           
            <!-- rename the 'lang' attribute on line 1166 to 'langAttribute' -->
           <jxb:bindings node="//xsd:element[@name='bdo']/xsd:complexType/xsd:complexContent/xsd:extension/xsd:attribute[@name='lang']">
                <jxb:property name="langAttribute"/>
           </jxb:bindings>
        </jxb:bindings>
    </jxb:bindings>
    

    I have tested with jaxb-ri-4.0.1 w jdk-17.0.2_8* with command line:

    xjc http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd -b cwe-bindings.xjb
    

    Output starts like this:

    parsing a schema...
    compiling a schema...
    com\example\cwe\A.java
    com\example\cwe\AContent.java
    com\example\cwe\Abbr.java
    
    • also works with jaxb-ri-2.3.0 and jdk1.8.0_231 - with jxb:bindings version="1.0" and xmlns:jxb="http://java.sun.com/xml/ns/jaxb"