You are trying to create an XML document from a Java object, and you want to customize the layout and structure of the generated XML document.
Use a Betwixt mapping file to customize the output of the
BeanWriter
. Below is an example of a mapping file
for the Play
class, which was introduced in
Recipe 6.2. When Betwixt serializes or deserializes
an object to or from XML, it will search for a resource,
<classname>.betwixt
, in the same package
as the class to be written or read. The following XML
document—Play.betwixt—
is stored in
the same package as the Play
class, and it
customizes the XML output from Betwixt:
<info primitiveTypes="element"> <element name="play"> <attribute name="genre" property="genre"/> <attribute name="year" property="year"/> <attribute name="language" property="language"/> <addDefaults/> </element> </info>
This file tells Betwixt that genre
,
year
, and language
shall be
stored as XML attributes, and that the remaining bean properties are
to be written as XML elements. The following code is used to create a
customized XML document from an instance of Play
:
import org.apache.commons.betwixt.io;
Play play = (Play) plays.get(0);
BeanWriter beanWriter = new
BeanWriter( );
beanWriter.enablePrettyPrint( );
beanWriter.write( play );
logger.debug( beanWriter.toString( ) );
Betwixt creates the following XML document, which stores the
genre
, year
, and
language
properties as attributes of the
play
element. The differences between this XML
document and the XML document in Recipe 6.7
are emphasized:
<play genre="tragedy" year="1603" language="english">
<author>William Shakespeare</author> <characters><character protagonist="false">
<description>King of Denmark</description> <name>Claudius</name> </character><character protagonist="true">
<description>Son to the late, and nephew of the present king</description> <name>Hamlet</name> </character><character protagonist="false">
<description>friend to Hamlet</description> <name>Horatio</name> </character> </characters> <name>Hamlet</name> <summary>Prince of Denmark (Hamlet) freaks out, talks to father's ghost, and finally dies in a duel.</summary> </play>
The previous example wrote the protagonist
property of the Character
class as an attribute of
the character
element. This customization was
accomplished by putting a Character.betwixt
resource in the same package as the Character
class. Character.betwixt
is shown here:
<info primitiveTypes="element"> <element name="character"> <attribute name="protagonist" property="protagonist"/> <addDefaults/> </element> </info>
In addition to customizing the structure on an XML document, a
Betwixt mapping file can also be used to change the names of elements
and attributes in an XML document. The following mapping
file—another version of
Character.betwixt—
writes the
description
property of
Character
as a bio
element:
<info primitiveTypes="element">
<element name="character">
<attribute name="protagonist" property="protagonist"/>
<element name="bio" property="description"/>
<addDefaults/>
</element>
</info>
In this recipe, Betwixt has wrapped all character
elements in a characters
element. If you prefer
character
elements to be child elements of
play
, you can tell the
XMLIntrospector
used by
BeanWriter
to omit elements wrapping collections
with the following code:
import org.apache.commons.betwixt.io.BeanWriter; import org.apache.commons.betwixt.XMLIntrospector; Play play = (Play) plays.get(0); BeanWriter beanWriter =new
BeanWriter( ); beanWriter.enablePrettyPrint( );// Configure XML Introspector to omit collection elements
XMLIntrospector introspector = beanWriter.getXMLIntrospector( );
introspector.setWrapCollectionsInElement(false);
beanWriter.write( play ); logger.debug( beanWriter.toString( ) );
The previous code creates an XML document without the
characters
element:
<play genre="tragedy" year="1603" language="english"> <author>William Shakespeare</author> <character protagonist="false"> <description>King of Denmark</description> <name>Claudius</name> </character> <character protagonist="true"> <description>Son to the late, and nephew of the present king</description> <name>Hamlet</name> </character> <character protagonist="false"> <description>friend to Hamlet</description> <name>Horatio</name> </character> <name>Hamlet</name> <summary>Prince of Denmark (Hamlet) freaks out, talks to father's ghost, and finally dies in a duel.</summary> </play>
Betwixt also allows for the customization of element and attribute
names; for example, if your class contains the property
maximumSpeed
, it can be written as an attribute
named maximum-speed
or
MAXIMUM_SPEED
, using the
HyphenatedNameMapper
strategy. The same property
could also be written as an element named
MaximumSpeed
, using the
CapitalizeNameMapper
strategy. Different naming
strategies can be used for elements and attributes by passing
instances of NameMapper
to
setElementNameMapper( )
and
setAttributeNameMapper( )
on an
XMLIntrospector
. The following code demonstrates
the setting of both the attribute and element
NameMapper
on a
BeanWriter
’s
XMLIntrospector
:
import org.apache.commons.betwixt.io.BeanWriter;
import org.apache.commons.betwixt.XMLIntrospector;
import org.apache.commons.betwixt.strategy.CapitalizeNameMapper;
import org.apache.commons.betwixt.strategy.HyphenatedNameMapper;
BeanWriter beanWriter = new
BeanWriter( );
// Set NameMappers on XMLIntrospector
XMLIntrospector introspector = beanWriter.getXMLIntrospector( );
introspector.setElementNameMapper( new CapitalizeNameMapper( ) );
introspector.setAttributeNameMapper( new HyphenatedNameMapper( ) );
beanWriter.write( object );
For more information about possible customizations in Betwixt, see the “Binding Beans” section of the user guide at http://jakarta.apache.org/commons/betwixt/guide/binding.html.
3.15.182.62