The WSIT Tutorial

generateElementProperty Attribute

WCF service WSDL generated from a programming language such as C# using DataContractSerializer may contain XML Schema constructs which result in JAXBElement<T> in generated code. A JAXBElement<T> type can also sometimes be generated when a WSDL contains advanced XML schema features such as substitution groups or elements that are both optional and nillable. In all such cases, JAXBElement<T> provides roundtripping support of values in XML instances. However, JAXBElement<T> is not natural to a Java developer. So the generateElementProperty customization can be used to generate an alternate developer friendly but lossy binding. The different bindings along with the trade-offs are discussed below.

Default Binding

The following is the default binding of an optional (minOccurs="0") and nillable(nillable="true") element:

//-- XML schema fragment
<xs:element name="person" type="Person"
<xs:complexType name="Person">
    <xs:sequence>
        <xs:element name="name" type="xs:string" 
                    nillable="true" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>
...

// Binding
public class Person {
    JAXBElement<String> getName() {...};
    public void setName(JAXBElement<String> value) {...}
}

Since the XML element name is both optional and nillable, it can be represented in an XML instance in one of following ways:

<!-- Absence of element name-->
<person>
    <-- element name is absent -->
</person>

<!-- Presence of an element name -->
<person>
    <name xsi:nil="true"/>
</person>

The JAXBElement<String> type roundtrips the XML representation of name element across an unmarshal/marshal operation.

Customized Binding

When generateElementProperty is false, the binding is changed as follows:

// set JAXB customization generateElementProperty="false"
public class Person {
    String getName() {...}
    public void setName(String value) {...}
}

The above binding is more natural to Java developer than JAXBElement<String>. However, it does not roundtrip the value of name.

JAXB 2.0 allows generateElementProperty to be set:

When processing a WCF service WSDL, it is recommended that the generateElementProperty customization be set in <jaxb:globalBindings>:

<jaxb:bindings version="2.0"
               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jaxb:bindings schemaLocation="schema-importedby-wcfsvcwsdl"
                   node="/xs:schema">
        <jaxb:globalBindings generateElementProperty="false"/>
    </jaxb:bindings>
    ...
	

Note –

The generateElementProperty attribute was introduced in JAXB 2.1.


mapSimpleTypeDef Attribute

XML Schema Part 2: Datatype defines facilities for defining datatypes for use in XML Schemas. .NET platform introduced the CLR types for some of the XML schema datatypes as described in Table 11–1.

Table 11–1 CLR to XML Schema Type Mapping

CLR Type 

XML Schema Type 

byte

xs:unsignedByte

uint

xs:unsignedInt

ushort

xs:unsignedShor

ulong

xs:unsignedLong

However, there are no corresponding Java types that map to the XML Schema types listed in Table 11–1. Furthermore, JAXB 2.0 maps these XML schema types to Java types that are natural to Java developer. However, this results in a mapping that is not one-to-one. For example:

The lack of a one-to-one mapping means that when XML Schema types shown in Table 11–1 are used in an xsi:type construct, they won’t be preserved by default across an unmarshal followed by marshal operation. For example:

// C# web method
public Object retObject(Object objvalue);
// Java web method generated from WCF service WSDL
public Object retObject(
    Object objvalue);
}

The following illustrates why xsi:type is not preserved across an unmarshal/marshal operation.

One way to preserve and roundtrip the xsi:type is to use the mapSimpleTypeDef customization. The customization makes the mapping of XML Schema Part 2 datatypes one--to-one by generating additional Java classes. Thus, xs:unsignedShort will be bound to its own class rather than int, as shown:

//Java class to which xs:unsignedShort is bound
public class UnsignedShort { ... }

The following illustrates how the xsi:type is preserved across an unmarshal/marshal operation:

Guideline: Use the mapSimpleTypedef customization where roundtripping of XML Schema types in Table 11–1 are used in xsi:type. However, it is preferable to avoid the use of CLR types listed in Table 11–1 since they are specific to .NET platform.

The syntax of the mapSimpleTypeDef customization is shown below.

<jaxb:bindings version="2.0"
               xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jaxb:bindings schemaLocation="schema-importedby-wcfsvcwsdl"
                   node="/xs:schema">
        <jaxb:globalBindings mapSimpleTypeDef="true"/>
    </jaxb:bindings>
    ....