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
Line 6: Line 6:
 
}}  
 
}}  
  
==Substitution Groups ==
+
=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'''. JAXB leverages existing XML schema concepts to produce very portable XML documents.   
 
With JAXB, you can use the element ''name'', instead of using the '''xsi:type''' attribute, to represent inheritance by using XML schema '''substitution groups'''. JAXB leverages existing XML schema concepts to produce very portable XML documents.   
  
Line 176: Line 176:
 
|next    =[[EclipseLink/UserGuide/MOXy/Advanced_XML_Schema_Concepts/Wildcard_Content|Wildcard Content]]
 
|next    =[[EclipseLink/UserGuide/MOXy/Advanced_XML_Schema_Concepts/Wildcard_Content|Wildcard Content]]
 
|up      =[[EclipseLink/UserGuide/MOXy/Advanced XML Schema Concepts|Advanced XML Schema Concepts]]
 
|up      =[[EclipseLink/UserGuide/MOXy/Advanced XML Schema Concepts|Advanced XML Schema Concepts]]
|version=2.2.0 DRAFT
+
|version=2.2.0  
 
}}
 
}}

Revision as of 12:40, 4 May 2011


Eclipselink-logo.gif
EclipseLink
Website
Download
Community
Mailing ListForumsIRCmattermost
Issues
OpenHelp WantedBug Day
Contribute
Browse Source


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. JAXB leverages existing XML schema concepts to produce very portable XML documents.


In this example, the Java model contains an abstract superclass for all types of contact information:

 
package blog.inheritance;
 
public abstract class ContactInfo {
 
}


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.

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 {
 
}


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).

 
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;
    }
 
}


This schema represents the JAXB view of the object model. The schema type inheritance matches the Java class inheritance.

 
<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>

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:

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>


Notice that the Address object is marshalled to the address element.



Eclipselink-logo.gif
Version: 2.2.0
Other versions...

Back to the top