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/Simple Values/Special Schema Types/Unions"

Line 93: Line 93:
 
   shoeSizeField.addConversion(XMLConstants.DECIMAL_QNAME, Float.class);
 
   shoeSizeField.addConversion(XMLConstants.DECIMAL_QNAME, Float.class);
 
</source>
 
</source>
 
 
=Mapping to a Union of Lists=
 
 
EclipseLink also supports mapping to lists of Unions, as demonstrated in the following schema:
 
 
<source lang="xml">
 
<?xml version="1.0" encoding="UTF-8"?>
 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 
  <xsd:element name="employee" type="employee-type"/> 
 
 
  <xsd:complexType name="employee-type">
 
      <xsd:sequence>
 
        <xsd:element name="vacation" type="union-of-lists"/>
 
      </xsd:sequence>
 
  </xsd:complexType>
 
 
  <xsd:simpleType name="union-of-lists">
 
      <xsd:union memberTypes="xsd:double">
 
        <xsd:simpleType>
 
            <xsd:list itemType="xsd:date"/>
 
        </xsd:simpleType>
 
 
        <xsd:simpleType>
 
            <xsd:list itemType="xsd:integer"/>
 
        </xsd:simpleType>
 
      </xsd:union>
 
  </xsd:simpleType>
 
</xsd:schema>
 
</source>
 
 
[[Image:dxuofl.gif]]<br><br>
 
 
Note that in this example, valid XML documents contain either a single '''xsd:double''' value, a list of '''xsd:date''' values, or a list of '''xsd:integer''' values.
 
 
This can be configured as follows:
 
 
<source lang="java">
 
package example;
 
 
import org.eclipse.persistence.config.DescriptorCustomizer;
 
import org.eclipse.persistence.descriptors.ClassDescriptor;
 
import org.eclipse.persistence.oxm.*;
 
 
public class VacationCustomizer implements DescriptorCustomizer {
 
 
  @Override
 
  public void customize(ClassDescriptor descriptor) throws Exception {
 
      XMLCompositeDirectCollectionMapping vacationMapping = new XMLCompositeDirectCollectionMapping();
 
      vacationMapping.setAttributeName("vacation");
 
      vacationMapping.setUsesSingleNode(false);
 
 
      XMLUnionField vacationField = new XMLUnionField();
 
      vacationField.setXPath("vacation/text()");
 
      vacationField.addSchemaType(XMLConstants.INTEGER_QNAME);
 
      vacationField.addSchemaType(XMLConstants.DOUBLE_QNAME);
 
      vacationField.addSchemaType(XMLConstants.DATE_QNAME);
 
      vacationField.setUsesSingleNode(false);
 
 
      vacationMapping.setField(vacationField);
 
 
      descriptor.addMapping(vacationMapping);
 
  }
 
 
}
 
</source>
 
 
 
=Mapping to a Union of Unions=
 
Given the XML schema in the [[#Example 58-20|Schema for XML Direct Mapping to a Union of Unions]] example, the [[#Figure 58-12|Java Class for XML Direct Mapping to a Union of Unions]] figure illustrates a Java class that can be mapped to a corresponding XML document. The [[#Example 58-21|Java for XML Direct Mapping to a Union of Unions]] example shows how to configure this mapping in Java.
 
 
 
<span id="Example 58-20"></span>
 
''''' Schema for XML Direct Mapping to a Union of Unions'''''
 
<?xml version="1.0" encoding="UTF-8"?>
 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 
    <xsd:element name="vacation" type="unionOfUnions"/>
 
    <xsd:simpleType name="unionOfUnions">
 
        <xsd:union>
 
 
            <xsd:simpleType>
 
                <xsd:union>
 
                    <xsd:simpleType>
 
                        <xsd:list itemType="xsd:date"/>
 
                    </xsd:simpleType>
 
                    <xsd:simpleType>
 
 
                        <xsd:list itemType="xsd:integer"/>
 
                    </xsd:simpleType>
 
                </xsd:union>
 
            </xsd:simpleType>
 
            <xsd:simpleType>
 
                <xsd:union>
 
 
                    <xsd:simpleType>
 
                        <xsd:list itemType="xsd:string"/>
 
                    </xsd:simpleType>
 
                    <xsd:simpleType>
 
                        <xsd:list itemType="xsd:float"/>
 
                    </xsd:simpleType>
 
 
                </xsd:union>
 
            </xsd:simpleType>
 
        </xsd:union>
 
    </xsd:simpleType>
 
</xsd:schema>
 
 
 
<span id="Figure 58-12"></span>
 
''''' Java Class for XML Direct Mapping to a Union of Unions'''''
 
 
[[Image:dxuofu.gif]]<br><br>
 
 
 
<span id="Example 58-21"></span>
 
''''' Java for XML Direct Mapping to a Union of Unions'''''
 
XMLDirectMapping vacationMapping = new XMLDirectMapping();
 
vacationMapping.setAttributeName("vacation");
 
XMLUnionField vacationField = new XMLUnionField();
 
vacationField.setXPath("vacation/text()");
 
vacationField.addSchemaType(XMLConstants.DATE_QNAME);
 
vacationField.addSchemaType(XMLConstants.INTEGER_QNAME);
 
vacationField.addSchemaType(XMLConstants.STRING_QNAME);
 
vacationField.addSchemaType(XMLConstants.FLOAT_QNAME);
 
vacationMapping.setField(vacationField);
 
 
  
  

Revision as of 13:22, 26 April 2011

EclipseLink MOXy

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

Mapping to a Union Field

The following XML schema and class diagram show a typical use of an XML Schema Union:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="customer" type="customer-type" />
    <xsd:complexType name="customer-type">
        <xsd:sequence>
            <xsd:element name="shoe-size" type="size-type" />
        </xsd:sequence>
    </xsd:complexType>
    <xsd:simpleType name="size-type">
        <xsd:union memberTypes="xsd:decimal xsd:string" />
    </xsd:simpleType>
</xsd:schema>

Dxmuc.gif

The figure below illustrates a mapping to a union field in an XML document that conforms to the example schema. When EclipseLink unmarshalls the XML document, it tries each of the union types until it can make a successful conversion. The first schema type in the union is xsd:decimal. Because "10.5" is a valid decimal, EclipseLink converts the value to the appropriate type.

Dxmuv.gif

In a second example document, the value "M" is not a valid xsd:decimal type, so the next union type is tried, xsd:string.

Dxmuvs.gif

Example

Currently, EclipseLink does not support the mapping of Unions using Annotations or OXM Metadata. However, an EclipseLink XML Customizer can be used to create the mapping.

First, we annotate the shoeSize attribute with @XmlTransient, to avoid automatically generating a mapping for it. We also include an @XmlCustomizer annotation; the CustomerCustomizer class will create the Union mapping in code.

package example;
 
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlCustomizer(EmployeeCustomizer.class)
public class Customer {
   @XmlTransient
   private Object shoeSize;
 
   ...
}


The CustomerCustomizer class can be used to manually add a mapping to the shoeSize attribute. Here, an XMLUnionField is configured on the mapping, and the possible Union member types are added by calling addSchemaType():

package example;
 
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.oxm.*;
 
public class CustomerCustomizer implements DescriptorCustomizer {
 
   @Override
   public void customize(ClassDescriptor descriptor) throws Exception {
      XMLDirectMapping shoeSizeMapping = new XMLDirectMapping();
      shoeSizeMapping.setAttributeName("shoeSize");
 
      XMLUnionField shoeSizeField = new XMLUnionField();
      shoeSizeField.setXPath("shoe-size/text()");
      shoeSizeField.addSchemaType(XMLConstants.DECIMAL_QNAME);
      shoeSizeField.addSchemaType(XMLConstants.STRING_QNAME);
 
      shoeSizeMapping.setField(shoeSizeField);
 
      descriptor.addMapping(shoeSizeMapping);
   }
 
}

EclipseLink uses a set of default conversions to create a value for the Java attribute (in this case, xsd:decimal will be converted into a BigDecimal). You can override this behavior in Java code using the XMLUnionField method addConversion. For example, if you want your Java object to store shoeSize as a Float:

   shoeSizeField.addConversion(XMLConstants.DECIMAL_QNAME, Float.class);


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

Back to the top