Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@XMLRootElement versus @XmlType

Tags:

xml

jaxb

jax-ws

What's the difference between annotating a class with @XMLRootElement and @XMLType. I've been annotating classes with @XMLType when the structure will be used more than once within an XML schema and with @XMLRootElement when it will be used only once - is this the best approach?

A different but related question which I'll include here. The @XMLType annotation has an propOrder attribute to specify in which order its elements appear - is there an equivalent for @XMLRootElement?

I'm using these annotations in conjunction with JAX-WS annotations to create web services if that makes any difference.

like image 432
CodeClimber Avatar asked Jul 17 '12 10:07

CodeClimber


People also ask

What is @XmlRootElement used for?

When a top level class or an enum type is annotated with the @XmlRootElement annotation, then its value is represented as XML element in an XML document. This annotation can be used with the following annotations: XmlType , XmlEnum , XmlAccessorType , XmlAccessorOrder .

What is @XmlType annotation in Java?

The annotation element propOrder() in the @XmlType annotation allows you to specify the content order in the generated schema type. When you use the @XmlType. propOrder annotation on a class to specify content order, all public properties and public fields in the class must be specified in the parameter list.

What is @XmlElement in Java?

Maps a JavaBean property to a XML element derived from property name. Usage. @XmlElement annotation can be used with the following program elements: a JavaBean property. non static, non transient field.


2 Answers

The difference between XmlRootElement and XmlType is a matter of scoping. Remember this annotation is merely dictating the creation of the schema used to generate your XML. The XmlRootElement denotes a global element (with an anonymous or schema type):

<xs:element name=foo type="bar"> </xs:element> <-- schema type 

while the XmlType is used to denote a local element (with an anonymous or complex type):

<xs:complexType name=bar> </xs:complexType> <-- complex type 

The main differences in local/global here are in the hierarchy of the schema your object will appear in and whether you are declaring a schema type or complex type. The documentation for both of these annotations is well written and includes examples:

XmlRootElement

XmlType

EDIT: Addressing the propOrder question: you can use it on a global element if you are also declaring a local type:

@XmlRootElement (name="PersonElement") @XmlType (propOrder={"firstname", "lastname"}) public class People{     @XmlElement     public String firstname;     public String lastname; } 

This will yield something like:

<xs:element name="PersonElement" type="People"/> <xs:complexType name="People">     <xs:sequence>         <xs:element name="firstname" type="xs:string"/>         <xs:element name="lastname" type="xs:string"/>     </xs:sequence> </xs:complexType> 
like image 193
DocWatson Avatar answered Nov 13 '22 01:11

DocWatson


I've been annotating classes with @XMLType when the structure will be used more than once within an XML schema and with @XMLRootElement when it will be used only once - is this the best approach?

One thing to know is that neither the @XmlRootElement or @XmlType annotation is required. They aren't the equivalent of @Entity from JPA. You can use a JAXB (JSR-222) implementation without any annotations what so ever:

  • http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted

Below I'll explain what @XmlRootElement and @XmlType do.


@XmlRootElement

There are times when your JAXB implementation needs to instantiate an object based only on the XML element that is being processed. The @XmlRootElement annotation is the primary means of specifying this association. Note if a class corresponds to more than one XML element then the @XmlElementDecl annotation should be used insteat,

ROLE #1 - Specifying the Root Object

@XmlRootElement is primarily used to specify the root object. This is so when your JAXB implementation begins unmarshalling an XML document it knows what object to instantiate. Almost all subsequent annotations will be based on information gathered from the parent class.

Foo

@XmlRootElement(name="root") public class Foo {      private String name;  } 

Bar

public class Bar {      private String name;  } 

XML

<root>     <name>Jane Doe</name> </root> 

Demo

Foo foo = (Foo) unmarshaller.unmarshal(xml); Bar bar = unmarshaller.unmarshal(xml, Bar.class).getValue(); 

ROLE #2 - Substitution Groups

The @XmlElementRef annotation delegates the type of object instantiated to the name/uri of the element. This enables the mapping to the concept of substitution groups for representing inheritance.

  • http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html

ROLE #3 - Any Content

@XmlAnyElement allows you to map a wild card section of your XML document. If you specify @XmlAnyElement(lax=true) then elements associated with domain objects will be converted to the corresponding domain object.

  • http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html

@XmlType

ROLE #1 - Schema Gen

By default a named complex type is generated for each Java class known to the JAXB context. You can control the name of this type using the @XmlType annotation, or specify that an anonymous complex type should be generated by specifying the name as "".

ROLE #2 - Inheritance and xsi:type

By default JAXB leverages the xsi:type attribute as the inheritance indicator. The value on this attribute corresponds to the name and namespace you have specified on the @XmlType annotation, or is defaulted based on the class.

  • http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html

ROLE #3 - Prop Order

As you mention you can use the @XmlType to specify the property order.

  • http://blog.bdoughan.com/2012/02/jaxbs-xmltype-and-proporder.html

ROLE #4 - Factory Methods

@XmlType allows you to specify a factory class and/or method that can be used to instantiate the domain object instead of the default constructor.

  • http://blog.bdoughan.com/2011/06/jaxb-and-factory-methods.html

A different but related question which I'll include here. The @XMLType annotation has an propOrder attribute to specify in which order it's elements appear - is there an equivalent for @XMLRootElement?

No, the propOrder aspect belongs to the @XmlType annotation. This makes sense since complex types are responsible for specifying an (or lack of) order. You can of course use these annotations at the same time.

@XmlRootElement @XmlType(propOrder={"foo", "bar"} public class Root {     ... } 
like image 27
bdoughan Avatar answered Nov 12 '22 23:11

bdoughan