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: Fri, 5 Mar 2010 19:53:04 +0100

Hi Oliver,

consider that XML data is "tagged" (and only occasionally "typed" using
xsi:type) and Java objects are "typed". Then, given a sequence of XML
elements, how can the distinctions by tag be maintained if that data is
converted to a sequence of Pojos?

Imagine all the possible variants how such a sequence can be defined in XML:
xs:maxOccurs > 1; xs:sequence's of elements; xs:sequence's of xs:choice's;
and so on, and in any combination. Moreover, the order of elements needs to
be preserved in the Java element hierarchy.

Java's fields do provide "tags", but only for a subset of the variety that
can be defined in XML Schema.

-W
PS: Thanks for the ack on the tutorial.

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

> Thanks Wolfgang -
>
> I had read over the substitutionGroup tutorial info on substitution groups.
> I am just having some trouble understanding what cases the JAXBElement
> strategy is absolutely necessary due to a schema's structure, and when it is
> not. It appears there is some flexibility there since I read that the
> 'simple' configuration optimizes away the JAXBElement in some cases - a
> capability that was added to the JAXB implementation late in the game based
> on user feedback. In the case I described, I don't see any impedance
> mismatch between the structure of the schema and what Java can represent, so
> I maintain some hope that there is a way of extending the 'simple'
> configuration to accomplish what I am after.
>
> There's no emergency with respect to time, so I'm really floating the idea
> to see if what I am after is a possibility for a future version, rather than
> asking for an immediate solution (though if anyone has any ideas I'm all
> ears). And, as I mentioned, I am happy to dig in and hack away if there
> isn't some fundamental problem with the idea, architecturally. Is this a
> more appropriate question for the Dev list, perhaps?
>
> Thanks again,
>
> -Oliver
>
>
> On Wed, Mar 3, 2010 at 2:14 PM, Wolfgang Laun <wolfgang.laun_at_gmail.com>wrote:
>
>> 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
>>>
>>
>>
>