EclipseLink Solutions Guide for EclipseLink
Release 2.4
  Go To Table Of Contents
 Search
 PDF

Mapping Simple Java Values to XML Text Nodes

This section demonstrates several ways to map simple Java values directly to XML text nodes. It includes the following examples:

Mapping a Value to an Attribute

This example maps the id property in the Java object Customer to its XML representation as an attribute of the <customer> element. The XML will be based on the schema in Example 15-10.

Example 15-10 Example XML Schema

<?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:attribute name="id" type="xsd:integer"/>
   </xsd:complexType>
 
</xsd:schema>

The following procedures demonstrate how to map the id property from the Java object and, alternately, how to represent the value in EclipseLink's Object-to-XML Mapping (OXM) metadata format.

Mapping from the Java Object

The key to creating this mapping from a Java object is the @XmlAttribute JAXB annotation, which maps the field to the XML attribute. To create this mapping:

  1. Create the object and import javax.xml.bind.annotation.*:

    package example;
     
    import javax.xml.bind.annotation.*;
    
  2. Declare the Customer class and use the @XmlRootElement annotation to make it the root element. Set the XML accessor type to FIELD:

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Customer {
    
  3. Map the id property in the Customer class as an attribute:

       @XmlAttribute
       private Integer id;
    

The object should look like Example 15-11.

Example 15-11 Customer Object with Mapped id Property

package example;
 
import javax.xml.bind.annotation.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
   @XmlAttribute
   private Integer id;
 
   ...
}

Defining the Mapping in OXM Metadata Format

If you want to represent the mapping in EclipseLink's OXM metadata format, you need to use the XML tags defined in the eclipselink-oxm.xml file and populate them with the appropriate values, as shown in Example 15-12.

Example 15-12 Mapping id as an Attribute in OXM Metadata Format

...
<java-type name="Customer">
   <xml-root-element name="customer"/>
   <java-attributes>
      <xml-attribute java-attribute="id"/>
   </java-attributes>
</java-type>
...

For more information about the OXM metadata format, see Using XML Metadata Representation to Override JAXB Annotations.

Mapping a Value to a Text Node

EclipseLink makes it easy for you to map values from a Java object to various kinds of XML text nodes; for example, to simple text nodes, text nodes in a simple sequence, in a subset, or by position. These mappings are demonstrated in the following examples:

Mapping a Value to a Simple Text Node

You can map a value from a Java object either by using JAXB annotations in the Java object or, alternately, by representing the mapping in EclipseLink's OXM metadata format.

Mapping by Using JAXB Annotations

Assuming the associated schema defines an element called <phone-number> which accepts a string value, you can use the @XmlValue annotation to map a string to the <phone-number> node. Do the following:

  1. Create the object and import javax.xml.bind.annotation.*:

    package example;
     
    import javax.xml.bind.annotation.*;
    
  2. Declare the PhoneNumber class and use the @XmlRootElement annotation to make it the root element with the name phone-number. Set the XML accessor type to FIELD:

    @XmlRootElement(name="phone-number")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class PhoneNumber {
    
  3. Insert the @XmlValue annotation on the line before the number property in the Customer class to map this value as an attribute:

       @XmlValue
       private String number;
    

The object should look like Example 15-13.

Example 15-13 PhoneNumber Object with Mapped number Property

package example;
 
import javax.xml.bind.annotation.*;
 
@XmlRootElement(name="phone-number")
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {
   @XmlValue
   private String number;
 
   ...
}

Defining the Mapping in OXM Metadata Format

If you want to represent the mapping in EclipseLink's OXM metadata format, you need to use the XML tags defined in the eclipselink-oxm.xml file and populate them with the appropriate values, as shown in Example 15-14.

Example 15-14 Mapping number as an Attribute in OXM Metadata Format

...
<java-type name="PhoneNumber">
   <xml-root-element name="phone-number"/>
   <java-attributes>
      <xml-value java-attribute="number"/>
   </java-attributes>
</java-type>
...

Mapping Values to a Text Node in a Simple Sequence

You can map a sequence of values, for example a customer's first and last name, as separate elements either by using JAXB annotations or by representing the mapping in EclipseLink's OXM metadata format. The following procedures illustrate how to map values for a customers' first names and last names

Mapping by Using JAXB Annotations

Assuming the associated schema defines the following elements:

  • <customer> of the type customer-type, which itself is defined as a complexType.

  • Sequential elements called <first-name> and <last-name>, both of the type string.

you can use the @XmlElement annotation to map values for a customer's first and last name to the appropriate XML nodes. To do so:

  1. Create the object and import javax.xml.bind.annotation.*:

    package example;
     
    import javax.xml.bind.annotation.*;
    
  2. Declare the Customer class and use the @XmlRootElement annotation to make it the root element. Set the XML accessor type to FIELD:

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Customer {
    
  3. Define the firstname and lastname properties and annotate them with the @XmlElement annotation. Use the name= argument to customize the XML element name (if you do not explicitly set the name with name=, the XML element will match the Java attribute name; for example, here the <first-name> element combination would be specified <firstName> </firstName> in XML).

       @XmlElement(name="first-name")
       private String firstName;
     
       @XmlElement(name="last-name")
       private String lastName;
    

The object should look like Example 15-15.

Example 15-15 Customer Object Mapping Values to a Simple Sequence

package example;
 
import javax.xml.bind.annotation.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
   @XmlElement(name="first-name")
   private String firstName;
 
   @XmlElement(name="last-name")
   private String lastName;
 
   ...
}

Defining the Mapping in OXM Metadata Format

If you want to represent the mapping in EclipseLink's OXM metadata format, you need to use the XML tags defined in the eclipselink-oxm.xml file and populate them with the appropriate values, as shown in Example 15-16.

Example 15-16 Mapping Sequential Attributes in OXM Metadata Format

...
<java-type name="Customer">
   <xml-root-element name="customer"/>
   <java-attributes>
      <xml-element java-attribute="firstName" name="first-name"/>
      <xml-element java-attribute="lastName" name="last-name"/>
   </java-attributes>
</java-type>
...

Mapping a Value to a Text Node in a Sub-element

You can map values from a Java object to text nodes that are nested as a subelement in the XML document by using JAXB annotations or by representing the mapping in EclipseLink's OXM metadata format. For example, if you want to populate <first-name> and <last-name> elements, which are sub-elements of a <personal-info> element under a <customer> root, you could use the following procedures to achieve these mappings.

Mapping by Using JAXB Annotations

Assuming the associated schema defines the following elements:

  • <customer> of the type customer-type, which itself is defined as a complexTpe.

  • <personal-info>

  • Sub-elements of <personal-info> called <first-name> and <last-name>, both of the type string

you can use JAXB annotations to map values for a customer's first and last name to the appropriate XML sub-element nodes. Because this example goes beyond a simple element name customization and actually introduces new XML structure, it uses EclipseLink's @XmlPath annotation. To achieve this mapping:

  1. Create the object and import javax.xml.bind.annotation.* and org.eclipse.persistence.oxm.annotations.*.

    package example;
     
    import javax.xml.bind.annotation.*;
    import org.eclipse.persistence.oxm.annotations.*;
    
  2. Declare the Customer class and use the @XmlRootElement annotation to make it the root element. Set the XML accessor type to FIELD:

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Customer {
    
  3. Define the firstName and lastName properties.

  4. Map the firstName and lastName properties to the sub-elements defined by the XML schema by inserting the @XmlPath annotation on the line immediately preceding the property declaration. For each annotation, define the mapping by specifying the appropriate XPath predicate:

       @XmlPath("personal-info/first-name/text()")
       private String firstName;
     
       @XmlPath("personal-info/last-name/text()")
       private String lastName;
    

The object should look like Example 15-17.

Example 15-17 Customer Object Mapping Properties to Sub-elements

package example;
 
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
   @XmlPath("personal-info/first-name/text()")
   private String firstName;
 
   @XmlPath("personal-info/last-name/text()")
   private String lastName;
 
   ...
}

Defining the Mapping in OXM Metadata Format

If you want to represent the mapping in EclipseLink's OXM metadata format, you need to use the XML tags defined in the eclipselink-oxm.xml file and populate them with the appropriate values, as shown in Example 15-18.

Example 15-18 Mapping Attributes as Sub-elements in OXM Metadata Format

...
<java-type name="Customer">
   <xml-root-element name="customer"/>
   <java-attributes>
      <xml-element java-attribute="firstName" xml-path="personal-info/first-name/text()"/>
      <xml-element java-attribute="lastName" xml-path="personal-info/last-name/text()"/>
   </java-attributes>
</java-type>
...

Mapping Values to a Text Node by Position

When multiple nodes have the same name, map their values from the Java object by specifying their position in the XML document. Do this by using mapping the values to the position of the attribute rather than the attribute's name. You can do this either by using JAXB annotations or by or by representing the mapping in EclipseLink's OXM metadata format. In the following example, XML contains two <name> elements; the first occurrence of name should represent the Customer's first name, the second name their last name.

Mapping by Using JAXB Annotations

Assuming an XML schema that defines the following attributes:

  • <customer> of the type customer-type, which itself is specified as a complexType

  • <name> of the type String

this example again uses the JAXB @XmlPath annotation to map a customer's first and last names to the appropriate <name> element. It also uses the @XmlType(propOrder) annotation to ensure that the elements are always in the proper positions. To achieve this mapping:

  1. Create the object and import javax.xml.bind.annotation.* and org.eclipse.persistence.oxm.annotations.XmlPath.

    package example;
     
    import javax.xml.bind.annotation.*;
    import org.eclipse.persistence.oxm.annotations.XmlPath;
    
  2. Declare the Customer class and insert the @XmlType(propOrder) annotation with the arguments "firstName" followed by "lastName". Insert the @XmlRootElement annotation to make Customer the root element and set the XML accessor type to FIELD:

    @XmlRootElement
    @XmlType(propOrder={"firstName", "lastName"})
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Customer {
    
  3. Define the properties firstName and lastName with the type String.

  4. Map the properties firstName and lastName to the appropriate position in the XML document by inserting the @XmlPath annotation with the appropriate XPath predicates.

        @XmlPath("name[1]/text()")
        private String firstName;
     
        @XmlPath("name[2]/text()")
        private String lastName;
    

    The predicates, "name[1]/text()" and "name[2]/text()" indicate the <name> element to which that specific property will be mapped; for example, "name[1]/text" will map the firstName property to the first <name> element.

The object should look like Example 15-19.

Example 15-19 Customer Object Mapping Values by Position

package example;
 
import javax.xml.bind.annotation.*;
 
import org.eclipse.persistence.oxm.annotations.XmlPath;
 
@XmlRootElement
@XmlType(propOrder={"firstName", "lastName"})
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
    @XmlPath("name[1]/text()")
    private String firstName;
 
    @XmlPath("name[2]/text()")
    private String lastName;
 
    ...
}

For more information about using XPath predicates, see Using XPath Predicates for Mapping.