users@jaxb.java.net

Bind existing class to existing schema HOWTO

From: Dmitri Colebatch <colebatchd_at_gmail.com>
Date: Tue, 21 Jun 2005 11:16:00 +1000

Hi all,

I figured I'd start by making a few notes on how what I'm learning so
that (a) others can correct me where I'm missing something, and (b)
someone else can benefit from it. What follows here is a very basic
outline of a few steps that I'm finding myself going through when
serializing an existing class.

Step one - decide whether you want to serialize fields (ie field
declarations) or properties (get/set methods). By default properties
are serialized. You need to put either:

    @XmlAccessorType(AccessType.FIELD)

or

    @XmlAccessorType(AccessType.PROPERTY)

at the top of your class depending on which approach you want to take.

Step two - identify the root element for the class, add the
appropriate annotation to the top of the class:

    @XmlRootElement(name = "ElementName", namespace = "ElementNamespace")

Having done this, give it a quick test, if you have something vaguely
resembling a javabean JAXB should spit something out - the top level
element will be ok, but you may find you need to tweak various bits
and pieces.

I've found setting field access (step one) is easiest (so far - I've
only just started!). So the rest of this assumes you're using field
access.

Step three - identify the type of the element, and the order of the
fields to be serialized. I'm assuming that your element is a complex
type, and it contains a sequence or all group. To identify the type
of element use the XmlType annotation. If your element contains an
anonymous type do this:

    @XmlType(name = "")

or if you have a global type, do this:

    @XmlType(name = "TypeName, namespace = "TypeNamespace")

Step four - Specify the order of the fields to be serialized. We do
this by adding the propOrder attribute (???) to the XmlType
annotation. Suppose you have two fields, foo and bar, and you want
foo to appear before bar, do this (note that I'm assuming you're using
an anonymous type, if you're using a global type change this to suit):

    @XmlType(name = "", propOrder = { "foo", "bar" })

Step five - Customize the mappings. Suppose you want foo to map to an
element called "SomethingElse" then find the field foo:

    private String foo;

and annotate it as follows:

    @XmlElement(name = "SomethingElse", namespace =
"ElementNamespace", type=String.class)
    private String foo;

Note also the namespace and type of the field.

Step six - Customize other types. Suppose bar is in fact another type:

    private MyClass bar;

public class MyClass
{
    private String a;
    private String b;

    // .... use your imagination!
}

and you want to map Bar to an element called "SomeRandomName", then
you need to do two things. Firstly, lets tell the field decl in our
first class that's the name of the element:

    @XmlElement(name = "SomeRandomName" namespace = "Namespace")
    private MyClass bar;

Secondly, we need to tell JAXB how to serialize MyClass. This is much
the same as for the top level class so I wont go through it again.

And that concludes my learning! Hopefully this is (a) accurate, (b)
sensible, and (c) helpful. I'll keep adding to this I think, and will
look forward to any constructive criticism or questions.

cheers
dim