Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "User:Rick.barkhouse.oracle.com/Test2"

(New page: {{EclipseLink_UserGuide |info=y |toc=y |api=y |apis= * [http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/jaxb/JAXBHelper.html JAXBHelper] * [http://www.eclipse.org/ecl...)
 
Line 3: Line 3:
 
|toc=y
 
|toc=y
 
|api=y
 
|api=y
|apis= * [http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/jaxb/JAXBHelper.html JAXBHelper]
+
|apis= * [http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/oxm/XMLNameTransformer.html XMLNameTransformer]
* [http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/jaxb/JAXBContext.html JAXBContext (EclipseLink)]
+
 
}}
 
}}
  
= Customizable Name Mangling Algorithm =
+
= Customizing XML Name Conversions =
 +
 
 +
JAXB has well-established rules for converting Java names to XML names which can be overridden through the use of annotations. This can become burdensome if your names follow common rules (such as making everything upper case).  As of EclipseLink 2.3 a new MOXy JAXB feature exists to allow you to override the default naming algorithm.
 +
 
 +
This example will create an implementation of '''org.eclipse.persistence.oxm.XMLNameTransformer''' to provide a naming algorithm to MOXy:
 +
 
 +
== Implementation ==
 +
<source lang="java">
 +
package examples;
 +
 
 +
public class NameMangler implements org.eclipse.persistence.oxm.XMLNameTransformer {
 +
 +
    //Use the unqualified class name as our root element name.
 +
    public String transformRootElementName(String name) {
 +
        return name.substring(name.lastIndexOf('.') + 1);
 +
    }
 +
 +
    //The same algorithm as root element name plus "Type" appended to the end.
 +
    public String transformTypeName(String name) {
 +
        return transformRootElementName(name) + "Type";
 +
    }
 +
 +
    //The name will be lower case with word breaks represented by '-'. 
 +
    //Note:  A capital letter in the original name represents the start of a new word.
 +
    public String transformElementName(String name) {
 +
        StringBuilder strBldr = new StringBuilder();
 +
        for(char character : name.toCharArray()) {
 +
            if(Character.isUpperCase(character)) {
 +
                strBldr.append('-');
 +
                strBldr.append(Character.toLowerCase(character));
 +
            } else {
 +
                strBldr.append(character);
 +
            }
 +
        }
 +
        return strBldr.toString();
 +
    }
 +
   
 +
    //The original name converted to upper case.
 +
    public String transformAttributeName(String name) {
 +
        return name.toUpperCase();
 +
    }
 +
 +
}
 +
</source>
 +
 
 +
== Java Model ==
 +
The following domain model will be used.  To save space the accessors have been omitted.
 +
 
 +
'''Customer'''
 +
 
 +
<source lang="java">
 +
import javax.xml.bind.annotation.*;
 +
 +
@XmlRootElement
 +
@XmlType(propOrder={"fullName", "shippingAddress"})
 +
@XmlAccessorType(XmlAccessType.FIELD)
 +
public class Customer {
 +
 +
    @XmlAttribute
 +
    private long id;
 +
 +
    private String fullName;   
 +
 
 +
    private Address shippingAddress;
 +
}
 +
</source>
 +
 
 +
'''Address.java'''
 +
 
 +
<source lang="java">
 +
import javax.xml.bind.annotation.*;
 +
 +
@XmlAccessorType(XmlAccessType.FIELD)
 +
public class Address {
 +
 +
    @XmlAttribute
 +
    private String type;
 +
 +
    private String street;
 +
 +
}
 +
</source>
 +
 
 +
== XML output using JAXB's default naming algorithm ==
 +
Using JAXB's default naming algorithm our object model will be converted to XML that looks like the following:
 +
 
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<customer id="123">
 +
    <fullName>Jane Doe</fullName>
 +
    <shippingAddress type="residential">
 +
        <street>1 Any Street</street>
 +
    </shippingAddress>
 +
</customer>
 +
</source>
 +
 
 +
== Specifying the naming algorithm ==
 +
Our implementation of the naming algorithm can be provided via the '''@XmlNameTransformer''' annotation (package or type level) or via the external bindings file in XML.
 +
 
 +
1. At the type level:
 +
<source lang="java">
 +
@XmlNameTransformer(examples.NameMangler.class)
 +
public class Customer
 +
</source>
 +
 
 +
2. At the package level (package-info.java):
 +
<source lang="java">
 +
@XmlNameTransformer(examples.NameMangler.class)
 +
package examples;
 +
</source>
 +
 
 +
3. External bindings file:
 +
<source lang="xml">
 +
<?xml version='1.0' encoding='UTF-8'?>
 +
<xml-bindings xmlns='http://www.eclipse.org/eclipselink/xsds/persistence/oxm' xml-name-transformer='examples.NameMangler'>
 +
  <xml-schema/>
 +
  <java-types/>
 +
</xml-bindings>
 +
</source>
 +
 
 +
For more information on how to use and specify a bindings file see the [http://wiki.eclipse.org/index.php?title=EclipseLink/Examples/MOXy/EclipseLink-OXM.XML EclipseLink-OXM.XML example].
 +
 
 +
== XML output using specified XMLNameTransformer ==
 +
By leveraging our customized naming algorithm we can get the following output without specifying any additional metadata on our domain classes:
 +
 
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<Customer ID="123">
 +
  <full-name>Jane Doe</full-name>
 +
  <shipping-address TYPE="residential">
 +
      <street>1 Any Street</street>
 +
  </shipping-address>
 +
</Customer>
 +
</source>
 +
 
 +
== Equivalent JAXB metadata ==
 +
Without overriding the naming algorithm, we would have had to specify additional JAXB metadata to get the desired XML output:
 +
 
 +
'''Customer'''
 +
 
 +
<source lang="java">
 +
import  javax.xml.bind.annotation.*;
 +
 +
@XmlRootElement(name="Customer")
 +
@XmlType(
 +
  name="CustomerType",
 +
  propOrder={"fullName", "shippingAddress"})
 +
@XmlAccessorType(XmlAccessType.FIELD)
 +
public class Customer {
 +
 +
    @XmlAttribute(name="ID")
 +
    private long id;
 +
 +
    @XmlElement(name="full-name")
 +
    private String fullName;
 +
   
 +
    @XmlElement(name="shipping-address")
 +
    private Address shippingAddress;
 +
 +
}
 +
</source>
 +
 
 +
'''Address'''
 +
 
 +
<source lang="java">
 +
import javax.xml.bind.annotation.*;
 +
 +
@XmlAccessorType(XmlAccessType.FIELD)
 +
@XmlType(name="AddressType")
 +
public class Address {
 +
 +
    @XmlAttribute(name="TYPE")
 +
    private String type;
 +
 +
    private String street;
 +
 +
}
 +
</source>

Revision as of 13:44, 17 June 2011


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

Customizing XML Name Conversions

JAXB has well-established rules for converting Java names to XML names which can be overridden through the use of annotations. This can become burdensome if your names follow common rules (such as making everything upper case). As of EclipseLink 2.3 a new MOXy JAXB feature exists to allow you to override the default naming algorithm.

This example will create an implementation of org.eclipse.persistence.oxm.XMLNameTransformer to provide a naming algorithm to MOXy:

Implementation

package examples;
 
public class NameMangler implements org.eclipse.persistence.oxm.XMLNameTransformer {
 
    //Use the unqualified class name as our root element name.
    public String transformRootElementName(String name) {
        return name.substring(name.lastIndexOf('.') + 1);
    }
 
    //The same algorithm as root element name plus "Type" appended to the end.
    public String transformTypeName(String name) {
        return transformRootElementName(name) + "Type";
    }
 
    //The name will be lower case with word breaks represented by '-'.  
    //Note:  A capital letter in the original name represents the start of a new word.
    public String transformElementName(String name) {
        StringBuilder strBldr = new StringBuilder();
        for(char character : name.toCharArray()) {
            if(Character.isUpperCase(character)) {
                strBldr.append('-');
                strBldr.append(Character.toLowerCase(character));
            } else {
                strBldr.append(character);
            }
         }
        return strBldr.toString();
    }
 
    //The original name converted to upper case.
    public String transformAttributeName(String name) {
        return name.toUpperCase();
    }
 
}

Java Model

The following domain model will be used. To save space the accessors have been omitted.

Customer

import javax.xml.bind.annotation.*;
 
@XmlRootElement
@XmlType(propOrder={"fullName", "shippingAddress"})
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
 
    @XmlAttribute
    private long id;
 
    private String fullName;     
 
    private Address shippingAddress;
}

Address.java

import javax.xml.bind.annotation.*;
 
@XmlAccessorType(XmlAccessType.FIELD)
public class Address {
 
    @XmlAttribute
    private String type;
 
    private String street;
 
}

XML output using JAXB's default naming algorithm

Using JAXB's default naming algorithm our object model will be converted to XML that looks like the following:

<?xml version="1.0" encoding="UTF-8"?>
<customer id="123">
    <fullName>Jane Doe</fullName>
    <shippingAddress type="residential">
        <street>1 Any Street</street>
    </shippingAddress>
</customer>

Specifying the naming algorithm

Our implementation of the naming algorithm can be provided via the @XmlNameTransformer annotation (package or type level) or via the external bindings file in XML.

1. At the type level:

@XmlNameTransformer(examples.NameMangler.class)
public class Customer

2. At the package level (package-info.java):

@XmlNameTransformer(examples.NameMangler.class)
package examples;

3. External bindings file:

<?xml version='1.0' encoding='UTF-8'?>
<xml-bindings xmlns='http://www.eclipse.org/eclipselink/xsds/persistence/oxm' xml-name-transformer='examples.NameMangler'>
   <xml-schema/>
   <java-types/>
</xml-bindings>

For more information on how to use and specify a bindings file see the EclipseLink-OXM.XML example.

XML output using specified XMLNameTransformer

By leveraging our customized naming algorithm we can get the following output without specifying any additional metadata on our domain classes:

<?xml version="1.0" encoding="UTF-8"?>
<Customer ID="123">
   <full-name>Jane Doe</full-name>
   <shipping-address TYPE="residential">
      <street>1 Any Street</street>
   </shipping-address>
</Customer>

Equivalent JAXB metadata

Without overriding the naming algorithm, we would have had to specify additional JAXB metadata to get the desired XML output:

Customer

import  javax.xml.bind.annotation.*;
 
@XmlRootElement(name="Customer")
@XmlType(
   name="CustomerType",
   propOrder={"fullName", "shippingAddress"})
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
 
    @XmlAttribute(name="ID")
    private long id;
 
    @XmlElement(name="full-name")
    private String fullName;
 
    @XmlElement(name="shipping-address")
    private Address shippingAddress;
 
}

Address

import javax.xml.bind.annotation.*;
 
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="AddressType")
public class Address {
 
    @XmlAttribute(name="TYPE")
    private String type;
 
    private String street;
 
}

Back to the top