Jump to: navigation, search

Difference between revisions of "EclipseLink/UserGuide/MOXy/Advanced Concepts/Customizing XML Name Conversions"

m (Replacing page with 'See http://www.eclipse.org/eclipselink/documentation/2.4/moxy/advanced_concepts002.htm')
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{EclipseLink_UserGuide
+
See http://www.eclipse.org/eclipselink/documentation/2.4/moxy/advanced_concepts002.htm
|info=y
+
|toc=y
+
|api=y
+
|apis= * [http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/oxm/XMLNameTransformer.html XMLNameTransformer]
+
}}
+
 
+
= 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).  EclipseLink MOXy '''2.3''' introduces a new feature to allow you to override the default naming algorithm.
+
 
+
This example will create an implementation of '''XMLNameTransformer''' to provide a naming algorithm to MOXy.
+
 
+
 
+
== XMLNameTransformer ==
+
 
+
The '''XMLNameTransformer''' interface defines several methods for customizing name generation:
+
 
+
* '''transformElementName''' - called when creating an element from a Java field or method
+
* '''transformAttributeName''' - called when creating an attribute from a Java field or method
+
* '''transformTypeName''' - called when creating a simple type or complex type from a Java class
+
* '''transformRootElementName''' - called when creating a (root) simple type or complex type from a Java class
+
 
+
 
+
The following example defines an '''XMLNameTransformer''' that does the following:
+
 
+
* Root element will be the unqualified Java class name
+
* Other types will be named (unqualified Java class name) + "Type"
+
* Camel-case element names will be converted to lower-case, hyphenated names
+
* XML attributes will appear in all upper-case
+
 
+
 
+
<source lang="java">
+
package example;
+
 
+
public class NameGenerator 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>
+
 
+
 
+
== Example 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>
+
 
+
 
+
== 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(example.NameGenerator.class)
+
public class Customer
+
</source>
+
 
+
2. At the package level (package-info.java):
+
<source lang="java">
+
@XmlNameTransformer(example.NameGenerator.class)
+
package example;
+
</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='example.NameGenerator'>
+
  <xml-schema/>
+
  <java-types/>
+
</xml-bindings>
+
</source>
+
 
+
 
+
== XML Output ==
+
 
+
Without any customization, JAXB's default naming algorithm will produce 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>
+
 
+
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>
+
 
+
 
+
== More Examples ==
+
 
+
For another example of custom name conversions, see:
+
 
+
* [[EclipseLink/Examples/MOXy/XMLNameTransformer|XMLNameTransformer Example]]
+

Latest revision as of 10:30, 8 November 2012

See http://www.eclipse.org/eclipselink/documentation/2.4/moxy/advanced_concepts002.htm