Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating Java classes out of XMLSchema.xsd using JAXB

Tags:

java

jaxb

I'm using jaxb to generate java classes out of a xml schema. The schema imports XMLSchema.xsd and its content is used as an element in the document.

If I remove the import and the reference to "xsd:schema" respectively then the binding compiler generates successfully the classes. If I do not then it would produce the following errors, which are the same if I would try to generate Java classes from the XMLSchema.xsd only!

>  C:\Users\me>"%JAXB%/xjc" -extension -d tmp/uisocketdesc -p uis.jaxb uisocketdesc.xsd -b xml_binding_test.xml -b xml_binding_test_2.xml
-b xml_binding_test_3.xml
parsing a schema...
compiling a schema...

> [ERROR] A class/interface with the same name "uis.jaxb.ComplexType" is already in use. Use a class customization to resolve this conflict.
 line 612 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "ComplexType" is generated from here.
 line 440 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.Attribute" is already in use. Use a class customization to resolve this conflict.
 line 364 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "Attribute" is generated from here.
 line 1020 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.SimpleType" is already in use. Use a class customization to resolve this conflict.
 line 2278 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "SimpleType" is generated from here.
 line 2222 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.Group" is already in use. Use a class customization to resolve this conflict.
 line 930 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "Group" is generated from here.
 line 727 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.AttributeGroup" is already in use. Use a class customization to resolve this conflict.
 line 1062 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "AttributeGroup" is generated from here.
 line 1026 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] A class/interface with the same name "uis.jaxb.Element" is already in use. Use a class customization to resolve this conflict.
 line 721 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Relevant to above error) another "Element" is generated from here.
 line 647 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 1020 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 364 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 2278 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 2222 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 930 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 727 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 440 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 612 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 1026 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 1062 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] Two declarations cause a collision in the ObjectFactory class.
 line 647 of "http://www.w3.org/2001/XMLSchema.xsd"

> [ERROR] (Related to above error) This is the other declaration.
 line 721 of "http://www.w3.org/2001/XMLSchema.xsd"

Failed to produce code.
like image 767
Christian Schulz Avatar asked Mar 09 '10 13:03

Christian Schulz


People also ask

How do I generate Java classes from XSD using JAXB in Intellij?

Generate a Java class from an XML Schema using JAXB In the active editor tab, open the desired Schema . xsd file or an XML document, which contains the desired Schema. In the main menu, go to Tools | XML Actions | Generate Java Code From XML Schema Using JAXB.

Which component or tool in JAXB can generate Java files from schemas?

You can create an XML schema document from an existing Java application that represents the data elements of a Java application by using the JAXB schema generator, schemagen command-line tool. The JAXB schema generator processes either Java source files or class files.


4 Answers

Fighting such stuff as well, for me it is case-sensitivity issue and the same name for element and attribute issue (thru inheritance sometimes). For the second problem I'm using external binding file that contains something like this:

<jaxb:bindings node="//xs:complexType[@name='AbstractGriddedSurfaceType']//xs:attribute[@name='rows']">
    <jaxb:property name="rowCount"/>
</jaxb:bindings>

For case-sensitivity issues you can use xjc argument -XautoNameResolution, maven version is <args><arg>-B-XautoNameResolution</arg></args>, but this doesn't work for wrapper elements, so for these you need to write jaxb customizations as mentioned above, ... and if you are unlucky like me :) you may need to use a local copy of an xsd and fix duplications manually.

Edit Found another solution for the case-sensitivity issue where renaming the element isn't enough:

<jaxb:bindings node=".//xs:element[@name='imageDatum'][@type='gml:ImageDatumPropertyType']">
    <jaxb:property name="imageDatumInst"/>
    <jaxb:factoryMethod name="imageDatumInst" />
</jaxb:bindings>

Good luck, hope this helps.

like image 192
tomasb Avatar answered Oct 18 '22 06:10

tomasb


You can successfully get JAXB to generate code for the XML Schema xsd by (at least) two methods. The problem you are experiencing stems from the fact that some schema types and elements share the same names.


The first option avoids name conflicts by applying one or more XML name transformations to the generated class names. Here is an example of an external binding file that will do this:

<jxb:bindings version="2.1"
               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jxb:extensionBindingPrefixes="xjc">  
  <jxb:globalBindings>
    <xjc:simple/>   
  </jxb:globalBindings>   
  <jxb:bindings schemaLocation="XMLSchema.xsd">
    <jxb:schemaBindings>
      <jxb:nameXmlTransform>
        <jxb:elementName suffix="Element"/>
      </jxb:nameXmlTransform>
    </jxb:schemaBindings>
  </jxb:bindings>  
</jxb:bindings>

This approach works (you could apply other transforms that would work just as well, but I've seen this technique over and over in the documentation) but I think it produces ugly results. For example, there is a generated class in this case named ElementElement.


The second approach uses class customization as suggested by the output of xjc. In fact, all but one of the problem classes has the property abstract="true" set in the corresponding schema type. Therefore it makes sense to me to prepend the class name with "Abstract", i.e. AbstractElement. The remaining Attribute class is not abstract, but the xs:element named attribute generates an extension class with an empty body. Therefore I called it BaseAttribute. Here is the external binding definition I used:

<jxb:bindings version="2.1"
               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jxb:extensionBindingPrefixes="xjc">
  <jxb:globalBindings>
    <xjc:simple/>
  </jxb:globalBindings>
  <jxb:bindings schemaLocation="XMLSchema.xsd">
    <jxb:schemaBindings>
      <jxb:package name="org.w3.xmlschema"/>
    </jxb:schemaBindings>
    <jxb:bindings node="//xs:complexType[@name='complexType']">
      <jxb:class name="AbstractComplexType"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='group']">
      <jxb:class name="AbstractGroup"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='attributeGroup']">
      <jxb:class name="AbstractAttributeGroup"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='simpleType']">
      <jxb:class name="AbstractSimpleType"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='element']">
      <jxb:class name="AbstractElement"/>
    </jxb:bindings> 
    <jxb:bindings node="//xs:complexType[@name='attribute']">
      <jxb:class name="BaseAttribute"/>
    </jxb:bindings> 
  </jxb:bindings>
</jxb:bindings>

This gives clearer generated class names in my opinion, and successfully compiles the schema.


I would also recommend using separate compilation for XMLSchema.xsd and keeping it in a jar file for later use in case this issue came up again while compiling another schema. The answers to this question describe how.

like image 30
Keith Layne Avatar answered Oct 18 '22 06:10

Keith Layne


Another option would be to remove the -p option so the classes are generated in different packages

like image 33
Christos Avatar answered Oct 18 '22 08:10

Christos


It looks like your schema is broken. XJC is extremely picky about these things, and can fail on things that other tools let through.

Rather than picking through XJC's errors, I find it easier to run the schema through the AlphaWorks Schema Quality Checker first. This gives a nice, human-readable (well, developer-readable, anyway) output of what's wrong. If it gets through that OK, you'll stand a much better chance of it getting through XJC too.

like image 40
skaffman Avatar answered Oct 18 '22 06:10

skaffman