Tag Archives: xjc

JAXB and creating elements from schema types

Working in the Java EE arena usually mean plenty of integrations – with other modules, with client applications, with third party providers, etc. Today, integrations always imply XML, and XML means some sort of definition – XML Schema, RelaxNG or “here is an example and you can figure it out yourself”. Personally I like XML schema – it’s a standard and relatively easy to understand (I know some will argue on this point). The best part is the fact I can use it to create objects for my application and save all the boilerplate marshalling and unmarshalling code. If there is one thing I hate, is to write code that should have be written by the compiler.

My tool of choice in the last few years is JAXB 2. Again, simple to understand, simple to work with, relatively descent documentation and integration with maven. However, there is one nagging problem with JAXB. When I need an element to be the root element of a document, as well as a child element I go into a corner. The trivial thing is to define a type, and then define an element of this type, in the following manner:

<?xml version="1.0" encoding="UTF-8"?>
<schema>
<complexType name="SomeType">
<sequence>
<element name="first-name" type="string"/>
<element name="last-name" type="string"/>
</sequence>
</complexType>
<element name="some-element" type="tns:SomeType"/>
</schema>

Naturally, I want to have the following code to get the simple XML:

SomeType s = new SomeType();
s.setFirstName("David");
s.setLastName("Rabinowitz");
marshaller.marshal(s);

This should yield

<some-element>
<first-name>David</first-name>
<last-name>Rabinowitz</last-name>
<some-element>

Unfortunately, the generated code lacks one important annotation from the generated class – the @XmlRootElement annotation, which lets the JAXB to know that it can use this element as the root element of the XML, and let it know the name of the root element.
Apperently I’m not the only one who have encountered this problem. Once I’ve received an XML schema from a content provider whom I should have written the integration with, and the instructions were: “If you want the sample code to work, generate the classes using XJC, then go to classes X, Y and Z and add the @XmlRootElement annotation to the class”. I can’t say I was very happy with this.

However, in the current schema I design, I found a solution which is not as simple as I wanted it to be, yet it solves the problem. The definition of some-element was changed to inherit from SomeType and now it looks like this:

<complexType name="some-element">
<complexContent>
<extension base="tns:SomeType"/>
</complexContent>
</complexType>

The generated code is quite similar:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "some-element")
public class SomeElement
extends SomeType
{ }

Now, all I need to do replace the first line in the above code sample to:

SomeElement s = new SomeElement();