users@jaxb.java.net

Re: Simple Java list - based binding for containers that support substitutionGroup semantics

From: Wolfgang Laun <wolfgang.laun_at_gmail.com>
Date: Wed, 3 Mar 2010 20:14:01 +0100

The JAXB tutorial <https://jaxb.dev.java.net/tutorial> discusses homogeneous
and mixed lists as well as substitution groups in some detail, so I won't
elaborate.

Please bear in mind that Java associates class field names with types,
whereas XML (and XML Schema) lets you defined structures that just don't map
to the more restrictive Java language. If you have a free hand to define the
schema, you can usually avoid JAXBElement<?> in the generated Java code; if
you don't you'll just have to make do.

-W


On Wed, Mar 3, 2010 at 6:21 PM, oliver newell <onewell43_at_gmail.com> wrote:

> Hi -
>
> I have a question regarding the form of the generated Java bindings for
> a list defined by the following schema fragment:
>
>
> <complexType name="RegistryObjectType">
> <sequence>
> <element name="Name" type="string" minOccurs="0" maxOccurs="1"/>
> <element name="Description" type="string" minOccurs="0"
> maxOccurs="1"/>
> </sequence>
> </complexType>
> <element name="RegistryObject" type="tns:RegistryObjectType"/>
>
> <complexType name="RegistryObjectListType">
> <annotation>
> <documentation xml:lang="en">
> Represents a list of RegistryObjectType instances.
> </documentation>
> </annotation>
> <sequence>
> <element ref="tns:RegistryObject" minOccurs="0"
> maxOccurs="unbounded" />
> </sequence>
> </complexType>
> <element name="RegistryObjectList" type="tns:RegistryObjectListType"/>
>
> <complexType name="AssociationType">
> <complexContent>
> <extension base="tns:RegistryObjectType">
> <attribute name="type" type="string" use="required"/>
> <attribute name="sourceObject" type="string" use="required"/>
> <attribute name="targetObject" type="string" use="required"/>
> </extension>
> </complexContent>
> </complexType>
>
>
> In XML documents that conform to this schema, I can put different
> types on the list using the xsi:type syntax, i.e.:
>
>
> <?xml version = "1.0" encoding = "UTF-8"?>
> <RegistryObjectList
> xmlns="http://oasis.org/ebxml/regrep/rim/4.0"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:schemaLocation="http://oasis.org/ebxml/regrep/rim/4.0../xsd/rim.xsd">
>
> <!-- Heterogeneous items on list specified using RegistryObject element
> and xsi:type -->
>
> <RegistryObject xsi:type="AssociationType" type="parentOf"
> sourceObject="obj1" targetObject="obj2" >
> <Name>Test Association</Name>
> </RegistryObject>
>
> </RegistryObjectList>
>
>
> If I do not define any elements that are substitutable for
> <RegistryObject>,
> then when I run the JAXB schema compiler I get a nice straightforward Java
> class, like:
>
>
> public class RegistryObjectListType {
> @XmlElement(name = "RegistryObject")
> protected List<RegistryObjectType> registryObject;
> ....
> }
>
> This interface is nice and easy to use.
>
>
>
> Now lets say that users of the schema want to support element-based
> substitution
> for list members in addition to (or instead of) the xsi:type mechanism,
> i.e.:
>
> <?xml version = "1.0" encoding = "UTF-8"?>
> <RegistryObjectList
> xmlns="http://oasis.org/ebxml/regrep/rim/4.0"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:schemaLocation="http://oasis.org/ebxml/regrep/rim/4.0../xsd/rim.xsd">
>
> <Association type="parentOf" sourceObject="obj1" targetObject="obj2">
> <Name>Test Association</Name>
> </Association>
>
> </RegistryObjectList>
>
> To support this usage in the XML Schema, an Association element is added to
>
> the original schema, and it is added to the substitution group for
> RegistryObject.
> The modified schema looks like:
>
> <complexType name="RegistryObjectType">
> <sequence>
> <element name="Name" type="string" minOccurs="0" maxOccurs="1"/>
> <element name="Description" type="string" minOccurs="0"
> maxOccurs="1"/>
> </sequence>
> </complexType>
> <element name="RegistryObject" type="tns:RegistryObjectType"/>
>
> <complexType name="RegistryObjectListType">
> <annotation>
> <documentation xml:lang="en">
> Represents a list of RegistryObjectType instances.
> </documentation>
> </annotation>
> <sequence>
> <element ref="tns:RegistryObject" minOccurs="0"
> maxOccurs="unbounded" />
> </sequence>
> </complexType>
> <element name="RegistryObjectList" type="tns:RegistryObjectListType"/>
>
> <complexType name="AssociationType">
> <complexContent>
> <extension base="tns:RegistryObjectType">
> <attribute name="type" type="string" use="required"/>
> <attribute name="sourceObject" type="string" use="required"/>
> <attribute name="targetObject" type="string" use="required"/>
> </extension>
> </complexContent>
> </complexType>
>
> <!-- ### New element that is substitutable for RegistryObject ### -->
> <element name="Association" type="tns:AssociationType"
> substitutionGroup="RegistryObject" />
>
> After this schema change, the generated Java class for the
> RegistryObjectListType now looks like:
>
>
> public class RegistryObjectListType {
>
> @XmlElementRef(name = "RegistryObject",
> namespace = "http://oasis.org/ebxml/regrep/rim-alt/4.0",
> type = JAXBElement.class)
> protected List<JAXBElement<? extends RegistryObjectType>>
> registryObject;
> ....
> }
>
> I find this interface with the JAXBElement wrapper around list elements
> much clunkier to use than the simple list. It seems like the information
> content
> of the XML is the same in either case - the extra element (in this case
> <Association> is in some sense
> just 'syntatic sugar' that for my use cases is equivalent to
> <RegistryObject xsi:type="AssociationType">.
> I am in search of a binding model that treats the two forms in an identical
> (simple) fashion.
>
> I see that by enabling the 'simple' JAXB extension, JAXBElement wrappers
> are removed in favor of more bare-bones
> Java classes. But that configuration setting doesn't seem to impact my
> particular case (substitutionGroup-based containers).
>
>
> Does anyone know of a way to configure JAXB to generate the simpler binding
> for
> RegistryObjectListType when element definitions that are substitutable
> RegistryObject
> as above are included in the schema? If not something that is currently
> 'tweakable',
> is there a way to do this with a plugin? Or a relatively simple patch to
> the JAXB
> implementation? (I would be willing if the concept wasn't fundamentally a
> non-starter and somebody could give me a hint)
>
>
> Thanks in advance for any advice,
>
> -Oliver
>
> P.S. A simple Maven-based project used to test the two variants is
> attached, in case there is any interest in it!
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>