Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EclipseLink/UserGuide/MOXy/Advanced XML Schema Concepts/Substitution Groups and Choices"

m
m (Replacing page with ''''Warning This page is obsolete. Please see ''[http://www.eclipse.org/eclipselink/documentation/2.4/ Developing JAXB Applications Using EclipseLi...')
 
(5 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{EclipseLink_UserGuide
+
'''[[Image:Elug_draft_icon.png|Warning]] This page is obsolete. Please see ''[http://www.eclipse.org/eclipselink/documentation/2.4/ Developing JAXB Applications Using EclipseLink MOXy]'' for current information.'''
|info=y
+
|api=y
+
|apis=* [http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/mappings/XmlElementRef.html XmlElementRef]
+
* [http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/mappings/XXmlRootElement.html XXmlRootElement]
+
}}
+
 
+
==Substitution Groups ==
+
With JAXB, you can use the element ''name'', instead of using the '''xsi:type''' attribute, to represent inheritance by using XML schema '''substitution groups'''.
+
 
+
 
+
In this example, the Java model contains an abstract superclass for all types of contact information:
+
 
+
<source lang="Java">
+
package blog.inheritance;
+
+
public abstract class ContactInfo {
+
+
}
+
 
+
</source>
+
 
+
 
+
The '''Address''' and '''PhoneNumber''' classes are the concrete implementations of '''ContactInfo'''.  Both classes use the '''@XmlRootElement''' annotation because the element name is used as the inheritance indicator.
+
 
+
<source lang="Java">
+
package blog.inheritance;
+
+
import javax.xml.bind.annotation.XmlRootElement;
+
+
@XmlRootElement
+
public class Address extends ContactInfo {
+
+
    private String street;
+
+
    public String getStreet() {
+
        return street;
+
    }
+
+
    public void setStreet(String street) {
+
        this.street = street;
+
    }
+
+
}
+
 
+
@XmlRootElement
+
public class PhoneNumber extends ContactInfo {
+
+
}
+
</source>
+
 
+
 
+
Because the '''Customer'' object can have different types of contact information, the property refers to the superclass. The '''contactInfo''' property contains the '''@XmlElementRef''' annotation to specify that the value type will be derived from the element name (and namespace URI).
+
 
+
<source lang="Java">
+
package blog.inheritance;
+
+
import javax.xml.bind.annotation.XmlElementRef;
+
import javax.xml.bind.annotation.XmlRootElement;
+
+
@XmlRootElement
+
public class Customer {
+
+
    private ContactInfo contactInfo;
+
+
    @XmlElementRef
+
    public ContactInfo getContactInfo() {
+
        return contactInfo;
+
    }
+
+
    public void setContactInfo(ContactInfo contactInfo) {
+
        this.contactInfo = contactInfo;
+
    }
+
+
}
+
 
+
</source>
+
 
+
 
+
This schema represents the JAXB view of the object model. The schema type inheritance matches the Java class inheritance. 
+
<source lang="xml">
+
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+
    <xs:element name="customer" type="customer"/>
+
+
    <xs:element name="contactInfo" type="contactInfo"/>
+
+
    <xs:element name="address" type="address"
+
        substitutionGroup="contactInfo"/>
+
+
    <xs:element name="phoneNumber" type="phoneNumber"
+
        substitutionGroup="contactInfo"/>
+
+
    <xs:complexType name="customer">
+
        <xs:sequence>
+
            <xs:element ref="contactInfo"/>
+
        </xs:sequence>
+
    </xs:complexType>
+
+
    <xs:complexType name="contactInfo" abstract="true">
+
        <xs:sequence/>
+
    </xs:complexType>
+
+
    <xs:complexType name="address">
+
        <xs:complexContent>
+
            <xs:extension base="contactInfo">
+
                <xs:sequence>
+
                    <xs:element name="street" type="xs:string" minOccurs="0"/>
+
                </xs:sequence>
+
            </xs:extension>
+
        </xs:complexContent>
+
    </xs:complexType>
+
+
    <xs:complexType name="phoneNumber">
+
        <xs:complexContent>
+
            <xs:extension base="contactInfo">
+
                <xs:sequence/>
+
            </xs:extension>
+
        </xs:complexContent>
+
    </xs:complexType>
+
+
</xs:schema>
+
 
+
</source>
+
 
+
Notice that each '''type''' has a corresponding global element.  Additionally, the '''address''' and '''phoneNumber''' elements may be substituted for the '''contactInfo''' element.
+
 
+
==Example ==
+
 
+
This example code demonstrates using the '''xsi:type''' attribute to represent inheritance:
+
 
+
<source lang="Java">
+
 
+
package blog.inheritance;
+
+
import javax.xml.bind.JAXBContext;
+
import javax.xml.bind.Marshaller;
+
+
public class Demo {
+
+
    public static void main(String[] args) throws Exception {
+
        Customer customer = new Customer();
+
        Address address = new Address();
+
        address.setStreet("1 A Street");
+
        customer.setContactInfo(address);
+
+
        JAXBContext jc = JAXBContext.newInstance(Customer.class, Address.class, PhoneNumber.class);
+
+
        Marshaller marshaller = jc.createMarshaller();
+
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+
        marshaller.marshal(customer, System.out);
+
    }
+
+
}
+
 
+
The example produces the following XML:
+
 
+
<source lang="xml">
+
+
<customer>
+
    <address>
+
        <street>1 A Street</street>
+
    </address>
+
</customer>
+
 
+
</source>
+
 
+
 
+
Notice that the '''Address''' object is marshalled to the '''address''' element.
+
 
+
 
+
 
+
 
+
How does this All Work?
+
 
+
 
+
Summary
+
 
+
Not all XML binding tools support inheritance.  The ones that do often use different strategies.  Some include the class name of the subclass as the qualifier, this strategy makes it difficult to send the resulting XML document to another tool.  JAXB on the other hand leverages existing XML schema concepts to produce very portable XML documents.  In a future post I'll discuss a MOXy extension for an alternate means of representing inheritance (check out the following for a sneak peak).
+
 
+
 
+
 
+
{{EclipseLink_MOXy
+
|previous=[[EclipseLink/UserGuide/MOXy/Advanced_XML_Schema_Concepts/Handling_Null_Values|Handling Null Values]]
+
|next    =[[EclipseLink/UserGuide/MOXy/Advanced_XML_Schema_Concepts/Wildcard_Content|Wildcard Content]]
+
|up      =[[EclipseLink/UserGuide/MOXy/Advanced XML Schema Concepts|Advanced XML Schema Concepts]]
+
|version=2.2.0 DRAFT
+
}}
+

Latest revision as of 13:12, 30 January 2013

Warning This page is obsolete. Please see Developing JAXB Applications Using EclipseLink MOXy for current information.

Back to the top