As of Enunciate 1.7, Enunciate supports both attributes and elements of a different namespace than their container type definitions. This answer is only application to Enunciate 1.6 and below. |
So you've got a schema to which you need to conform and it requires child elements of a different namespace than their containing type definitions. For example:
The above XML fragment shows an outer "person" element that contains as a child element an "address" element. The address element is declared within a different namespace than the person element.
The Schemas
Let's take a look at how these elements are defined by XML Schema. Because each schema file contains element definitions for a single namespace, the above XML must be defined by two separate schemas, one for the "uri:personal-info" namespace, and one for the "uri:address-info" namespace:
And the schema definition file "address-info.xsd":
Note that in the definition for the "person" type, the "address" child element is actually a reference to the "address" element defined in the other schema.
The Java Types
Let's see how these definitions could be declared in Java using JAXB 2.0. The simplest way is to define the two classes, "Person" and "Address", and to use the @XmlElement annotation to declare the reference from the Person to the Address.
Person.java:
Address.java:
Enunciate's Limitations
Currently, applying Enunciate to the classes above will produce a message that says something like "Enunciate doesn't support elements of a different namespace than their containing type definition...." This is because Enunciate does not take into account these "implied" element references while generating the schema files for each namespace. There is, however, a workaround:
The Workaround
The workaround requires the definition of the "address" element as a root element for its namespace and using the @XmlElementRef annotation to reference it from the Person class:
Person.java:
Address.java:
Note, however, that this only works if the name of the child element is "address". If the name of the child element must be different from the name of the root element, you must create a third wrapper class that is a root element of the name of the child element. Say, for example, you wanted to specify the child element as "homeAddress" instead of just address. You would need three classes, like this:
Person.java:
Address.java:
HomeAddress.java:
