Reality-Loop

JAXB Quicktip: XMLGregorianCalendar

May 08, 2009 | 1 Minute Read
This post was originally posted on my old blog.

Assume you have the following type-declaration in your XSD:

<xs:simpleType name="dateType">
	<xs:annotation> 
		<xs:documentation>Date without Timezone with the following format: YYYY-MM-DD</xs:documentation>
	</xs:annotation>
	<xs:restriction base="xs:date">
		<xs:pattern value="\d{4}-\d{2}-\d{2}"/>
	</xs:restriction> 
</xs:simpleType> 

If you are using XJC to generate Java classes from the above XSD, then references of Type XMLGregorianCalendar are generated.

Now, if you instantiate a new XMLGregorianCalendar in your Java code like this:

GregorianCalendar cal = new GregorianCalendar( 1976, Calendar.DECEMBER, 22 );
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar( cal );

… and then let JAXB render the xml, the corresponding XML looks like this:

<birthday>1976-12-22T00:00:00.000+01:00</birthday>

… this XML fragment is not valid according to the above schema!
What we want would look like this:

<birthday>1976-12-22</birthday>

An quick workaround is to set the unwanted fields of XMLGregorianCalendar to DatatypeConstants.FIELD_UNDEFINED like this:

XMLGregorianCalendar gc = DatatypeFactory.newInstance().newXMLGregorianCalendar( c );
gc.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
gc.setTime(DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);

Of course it would be much cleaner if JAXB would respect the constraints when generating the Java code. I guess this could be achieved by configuring JAXB accordingly … but I did not go so far.

 

http://www.google.com/s2/favicons?domain=twitter.com follow me on twitter, I need some friends :-)