Question

I am using Jaxb to generate Java classes. My schema has the following element defined:

<xs:complexType name="AutomobileType" abstract="true">
    <xs:sequence>
        <xs:element name="Color" type="core:ColorName"/>
        <xs:element name="Weight" type="core:PoundsWeightType"/>
        <xs:element name="Fuel" type="Fuel"/>
        <xs:element name="NumDoors" type="xs:nonNegativeInteger"/>
        <xs:element name="NumCylinders">
            <xs:simpleType>
                <xs:restriction base="xs:int">
                    <xs:minInclusive value="1"/>
                    <xs:maxInclusive value="12"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:element>
    </xs:sequence>
</xs:complexType>    
<xs:element name="Automobile" type="AutomobileType"/>

As you can see, I have one element called Automobile.

Jaxb creates the classes and an ObjectFactory that I use to create instances of Automobile. The thing that baffles me is the method to create an instance of Automobile is as follows:

public JAXBElement<AutomobileType> createAutomobile(AutomobileType value)

Why does the createAutomobile method have an argument? How do I use this method?

I tried the following:

ObjectFactory objectFactory = new ObjectFactory();
objectFactory.createAutomobile(new Automobile());

but this does not compile because the Automobile class is abstract and therefore I cannot create an instance.

Was it helpful?

Solution

There is another method :

 public AutomobileType createAutomobileType();

In JAXB, the xsd:complexType "AutomobileType" construct maps the class of the same name. It is meant to be the data structure that is equivalent to that XML schema type.

The JAXBElement<> is a (parameterized) wrapper type that associates the java object and the element name and namespace, and that's why its constructor takes an AutomobileType object as parameter in the constructor, in addition to the element namespace and the element name. The generated ObjectFactory "createAutomobile(..)" is just a convenience method to wrap that constructor, hard-coding your namespace and element name from your XML schema.

While this dichotomy is not all straight forward at first, consider that you could have another element by another name

They would be structurally equivalent, but the element name would be different. You would have another ObjectFactory method "createMotorcycle(...)".

You can create an un-named automobileType object for the purpose of building the contents of the xml element, and then tell JAXB exactly which XML element it should be represented as.

I can't recommend enough reading the JAXB documentation on the topic.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top