users@jaxb.java.net

Re: Retrieving substitutionGroup information from JAXBElement

From: Claus Nagel <claus.nagel_at_gmail.com>
Date: Wed, 30 Sep 2009 17:52:57 +0200

Hi Wolfgang,

> Can you please explain why?

Ok, I will do my very best. I am working with an XML schema associated
with the namespace "foo". This schema provides a complex type
definition "foo:A" which contains property elements of the following
type:

[Schema "foo"]
<xs:complexType name="foo:A">
...
   <xs:element ref="foo:_GenericExtensionTypeA" minOccurs="0"/>
   <xs:element ref="foo:_GenericExtensionTypeB" minOccurs="0"/>
</xs:complexType>

<xs:element name="foo:_GenericExtensionTypeA" abstract="true"
type="xs:anyType"/>
<xs:element name="foo:_GenericExtensionTypeB" abstract="true"
type="xs:anyType"/>

These elements provide a generic extension mechanism for the type
foo:A. For example, a user wants to use foo:A but he lacks an
additional property which he needs to exchange with this type. This
additional property can be declared within _another_ user-defined XML
schema document (for example associated with the namespace "bar") and
can be injected into foo:A in the following way:

[Schema "bar"]
<xs:element name="bar:NewProperty" type="xs:string"
substitutionGroup="foo:_GenericExtensionTypeA"/>

This extension mechanism is quite powerful, however, in my project I
only have the XML schema "foo" at hand and can bind it to JAXB
classes. Possible user-defined extensions (i.e., additional XML
schemas) are not known a priori and, thus, I cannot create
corresponding JAXB classes.

Additionally, I have to meet the following requirement: The XML parser
must read any content in the XML document (i.e., also user-defined
extensions) and when it comes to writing the content back to a file,
all user-defined extensions must still be contained in the output
document. Thus, any content the parser cannot interpret must be
"passed through" the processing pipeline.

In reality, the schema "foo" is a very complex schema which even
imports many other schemas. I have written an API for that schema
based on JAXB which makes it easy to read and write valid XML
documents (and in fact, JAXB made my life easy at this point). But now
the support for generic user-defined extensions makes me some headache.

This is what I want to achieve:
* The API already supports adding further JAXB classes which map user-
defined content (the user has to create these classes).
* However, for all other user-defined content I need a more generic
solution.

This is my approach: I followed the article "Avoid strong databinding"
in the JAXB guide to map unknown content to DOM elements, for example:

[Schema "foo"]
<xs:element name="foo:_GenericExtensionTypeA" abstract="true"
type="xs:anyType">
   <xs:annotation>
     <xs:appinfo>
       <jaxb:dom/>
     </xs:appinfo>
   </xs:annotation>
</xs:element>

The drawback: JAXB nicely creates DOM elements for user-defined
extensions but they are all associated with
"foo:_GenericExtensionTypeA" since this element is declared right
before "foo:_GenericExtensionTypeB" within the type "foo:A". This
means, for the resulting class "foo:A" _all_ DOM elements are returned
as list via the method "get_GenericExtensionTypeA()". However, the
"get_GenericExtensionTypeB()" method will always return an empty list.

If I come across a DOM element while parsing an XML document I first
check whether there are user-defined JAXB classes which can bind the
DOM element. If the Unmarshaller cannot bind the DOM element, I still
have to check the substitution group for the element in order to
decide whether I have to put it into the list representing
"foo:_GenericExtensionTypeA" or into the list for
"foo:_GenericExtensionTypeB". I am using XSOM for this purpose. If,
however, the Unmarshaller succeeds in binding the DOM element and
returns a JAXBElement<?> (well, this is the point where I started my
initial post...) I still have to check the proper substitution group.

At this point I hope there is a better (and faster) way to retrieve
the substitution group of an JAXBElement<?> than parsing all the
schema documents using XSOM.

Any suggestions on retrieving the substitution group information from
an JAXBElement<?>?

Cheers,
Claus


Am 30.09.2009 um 11:22 schrieb Wolfgang Laun:

> On Wed, Sep 30, 2009 at 10:27 AM, Claus Nagel
> <claus.nagel_at_gmail.com> wrote:
> Hi all -
>
> in a current project I get JAXBElement<?> objects returned from the
> unmarshal method of the JAXB Unmarshaller. In order to correctly
> process these objects I need to know whether or not the
> xs:substitutionGroup attribute is set for the corresponding
> xs:element in the XML Schema document.
>
> Can you please explain why?
>
> You should be able to distinguish the element alternatives resulting
> from the group by looking at the XML element tag.
>
> -W
>
>
> Is there an easy way to query the JAXBElement<?> object in order to
> get this information? Or do I need to parse the ObjectFactory class
> using Java reflection? If I have to parse the ObjectFactory class,
> does the JAXBElement<?> contain a link to the proper class (because
> I have to deal with plenty of ObjectFactory classes and want to
> avoid scanning all of them...). Or is there a completely different
> approach possible?
>
> Thanks for any suggestions,
> Cheers,
> Claus
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>
>