@XMLRootElement versus @XmlType

前端 未结 2 1573
小蘑菇
小蘑菇 2020-12-13 17:59

What\'s the difference between annotating a class with @XMLRootElement and @XMLType. I\'ve been annotating classes with @XMLType when

相关标签:
2条回答
  • 2020-12-13 18:32

    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>
    
    0 讨论(0)
  • 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 {
        ...
    }
    
    0 讨论(0)
提交回复
热议问题