How to use JAXBElement
JAXBElement is used in JAXB where the XML Schema can not be represented by a Java bean. You will often encounter it when compiling complex XML Schema documents with xjc. Each JAXBElement corresponds to an XML element. It stores the element's tag name as well as its content. The content of a JAXBElement can be any object supported by JAXB, beans or simple types.
The following example
Movie movieContent = new Movie("Casablanca", 1942);
JAXBElement<Movie> myMovie = new JAXBElement<Movie>(new QName("myMovie"),
Movie.class, movieContent);
JAXB.marshal(myMovie, new File("/tmp/movie.xml"));
will create this XML:
<myMovie>
<releaseYear>1942</releaseYear>
<title>Casablanca</title>
</myMovie>
Note that the tag name of the generated element is not Movie, but myMovie, as specified in the JAXBElement.
JAXBElement for Choice
Here is an example for a XML Schema that will need JAXBElement:
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="movieSoSoLibrary">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="goodMovie" type="movie" nillable="true"/>
<xs:element name="badMovie" type="movie" nillable="true"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:complexType name="movie">
<xs:sequence>
<xs:element name="releaseYear" type="xs:int"/>
<xs:element name="title" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
In this example, the tag names goodMovie and badMovie can both be used to represent the movie type. In order to differentiate a goodMovie from a badMovie, even though both are represented by the Movie class, xjc will create the following code:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "goodMovieOrBadMovie" })
@XmlRootElement(name = "movieSoSoLibrary")
public class MovieSoSoLibrary {
@XmlElementRefs({
@XmlElementRef(name = "goodMovie", type = JAXBElement.class),
@XmlElementRef(name = "badMovie", type = JAXBElement.class)
})
protected List<JAXBElement<Movie>> goodMovieOrBadMovie;
public List<JAXBElement<Movie>> getGoodMovieOrBadMovie() {
if (goodMovieOrBadMovie == null) {
goodMovieOrBadMovie = new ArrayList<JAXBElement<Movie>>();
}
return this.goodMovieOrBadMovie;
}
}
When xjc generates such code, it places factory methods for the JAXBElement instances into a class called ObjectFactory. There you can find the following definitions for creating goodMovie and badMovie elements:
@XmlElementDecl(namespace = "", name = "badMovie", scope = MovieSoSoLibrary.class)
public JAXBElement<Movie> createMovieSoSoLibraryBadMovie(Movie value) {
return new JAXBElement<Movie>(_MovieSoSoLibraryBadMovie_QNAME,
Movie.class, MovieSoSoLibrary.class, value);
}
@XmlElementDecl(namespace = "", name = "goodMovie", scope = MovieSoSoLibrary.class)
public JAXBElement<Movie> createMovieSoSoLibraryGoodMovie(Movie value) {
return new JAXBElement<Movie>(_MovieSoSoLibraryGoodMovie_QNAME,
Movie.class, MovieSoSoLibrary.class, value);
}
Note that the @XmlElementRef annotations in the MovieSoSoLibrary refer to the @XmlElementDecl annotations in ObjectFactory.