Chapter 33. Using XML Elements
Abstract
XML Schema elements are used to define an instance of an element in an XML document. Elements are defined either in the global scope of an XML Schema document, or they are defined as a member of a complex type. When they are defined in the global scope, Apache CXF maps them to a JAXB element class that makes manipulating them easier.
Overview
An element instance in an XML document is defined by an XML Schema element
element in the global scope of an XML Schema document To make it easier for Java developers to work with elements, Apache CXF maps globally scoped elements to either a special JAXB element class or to a Java class that is generated to match its content type.
How the element is mapped depends on if the element is defined using a named type referenced by the type
attribute or if the element is defined using an in-line type definition. Elements defined with in-line type definitions are mapped to Java classes.
It is recommended that elements are defined using a named type because in-line types are not reusable by other elements in the schema.
XML Schema mapping
In XML Schema elements are defined using element
elements. element
elements has one required attribute. The name
specifies the name of the element as it appears in an XML document.
In addition to the name
attribute element
elements have the optional attributes listed in Table 33.1, “Attributes Used to Define an Element”.
Attribute | Description |
---|---|
| Specifies the type of the element. The type can be any XML Schema primitive type or any named complex type defined in the contract. If this attribute is not specified, you will need to include an in-line type definition. |
|
Specifies if an element can be left out of a document entirely. If |
|
Specifies if an element can be used in an instance document. |
| Specifies the name of an element that can be substituted with this element. For more information on using type substitution see Chapter 37, Element Substitution. |
| Specifies a default value for an element. For information on how this attribute effects code generation see the section called “Java mapping of elements with a default value”. |
| Specifies a fixed value for the element. |
Example 33.1, “Simple XML Schema Element Definition” shows a simple element definition.
Example 33.1. Simple XML Schema Element Definition
<element name="joeFred" type="xsd:string" />
An element can also define its own type using an in-line type definition. In-line types are specified using either a complexType
element or a simpleType
element. Once you specify whether the type of data is complex or simple, you can define any type of data needed using the tools available for each type of data.
Example 33.2, “XML Schema Element Definition with an In-Line Type” shows an element definition with an in-line type definition.
Example 33.2. XML Schema Element Definition with an In-Line Type
<element name="skate"> <complexType> <sequence> <element name="numWheels" type="xsd:int" /> <element name="brand" type="xsd:string" /> </sequence> </complexType> </element>
Java mapping of elements with a named type
By default, globally defined elements are mapped to JAXBElement<T>
objects where the template class is determined by the value of the element
element’s type
attribute. For primitive types, the template class is derived using the wrapper class mapping described in the section called “Wrapper classes”. For complex types, the Java class generated to support the complex type is used as the template class.
To support the mapping and to relieve the developer of unnecessary worry about an element’s QName, an object factory method is generated for each globally defined element, as shown in Example 33.3, “Object Factory Method for a Globally Scoped Element”.
Example 33.3. Object Factory Method for a Globally Scoped Element
public class ObjectFactory { private final static QName _name_QNAME = new QName("targetNamespace", "localName"); ... @XmlElementDecl(namespace = "targetNamespace", name = "localName") public JAXBElement<type> createname(type value); }
For example, the element defined in Example 33.1, “Simple XML Schema Element Definition” results in the object factory method shown in Example 33.4, “Object Factory for a Simple Element”.
Example 33.4. Object Factory for a Simple Element
public class ObjectFactory { private final static QName _JoeFred_QNAME = new QName("...", "joeFred"); ... @XmlElementDecl(namespace = "...", name = "joeFred") public JAXBElement<String> createJoeFred(String value); }
Example 33.5, “Using a Globally Scoped Element” shows an example of using a globally scoped element in Java.
Example 33.5. Using a Globally Scoped Element
JAXBElement<String> element = createJoeFred("Green"); String color = element.getValue();
Using elements with named types in WSDL
If a globally scoped element is used to define a message part, the generated Java parameter is not an instance of JAXBElement<T>
. Instead it is mapped to a regular Java type or class.
Given the WSDL fragment shown in Example 33.6, “WSDL Using an Element as a Message Part”, the resulting method has a parameter of type String
.
Example 33.6. WSDL Using an Element as a Message Part
<?xml version="1.0" encoding=";UTF-8"?> <wsdl:definitions name="HelloWorld" targetNamespace="http://apache.org/hello_world_soap_http" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://apache.org/hello_world_soap_http" xmlns:x1="http://apache.org/hello_world_soap_http/types" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <wsdl:types> <schema targetNamespace="http://apache.org/hello_world_soap_http/types" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"><element name="sayHi"> <element name="sayHi" type="string"/> <element name="sayHiResponse" type="string"/> </schema> </wsdl:types> <wsdl:message name="sayHiRequest"> <wsdl:part element="x1:sayHi" name="in"/> </wsdl:message> <wsdl:message name="sayHiResponse"> <wsdl:part element="x1:sayHiResponse" name="out"/> </wsdl:message> <wsdl:portType name="Greeter"> <wsdl:operation name="sayHi"> <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/> <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/> </wsdl:operation> </wsdl:portType> ... </wsdl:definitions>
Example 33.7, “Java Method Using a Global Element as a Part” shows the generated method signature for the sayHi
operation.
Example 33.7. Java Method Using a Global Element as a Part
String
sayHi
String
in
Java mapping of elements with an in-line type
When an element is defined using an in-line type, it is mapped to Java following the same rules used for mapping other types to Java. The rules for simple types are described in Chapter 34, Using Simple Types. The rules for complex types are described in Chapter 35, Using Complex Types.
When a Java class is generated for an element with an in-line type definition, the generated class is decorated with the @XmlRootElement
annotation. The @XmlRootElement
annotation has two useful properties: name
and namespace
. These attributes are described in Table 33.2, “Properties for the @XmlRootElement Annotation”.
Property | Description |
---|---|
|
Specifies the value of the XML Schema |
| Specifies the namespace in which the element is defined. If this element is defined in the target namespace, the property is not specified. |
The @XmlRootElement
annotation is not used if the element meets one or more of the following conditions:
-
The element’s
nillable
attribute is set totrue
The element is the head element of a substitution group
For more information on substitution groups see Chapter 37, Element Substitution.
Java mapping of abstract elements
When the element’s abstract
attribute is set to true
the object factory method for instantiating instances of the type is not generated. If the element is defined using an in-line type, the Java class supporting the in-line type is generated.
Java mapping of elements with a default value
When the element’s default
attribute is used the defaultValue
property is added to the generated @XmlElementDecl
annotation. For example, the element defined in Example 33.8, “XML Schema Element with a Default Value” results in the object factory method shown in Example 33.9, “Object Factory Method for an Element with a Default Value”.
Example 33.8. XML Schema Element with a Default Value
<element name="size" type="xsd:int" default="7"/>
Example 33.9. Object Factory Method for an Element with a Default Value
@XmlElementDecl(namespace = "...", name = "size", defaultValue = "7")
public JAXBElement<Integer> createUnionJoe(Integer value) {
return new JAXBElement<Integer>(_Size_QNAME, Integer.class, null, value);
}