users@jaxb.java.net

Re: Retrieving substitutionGroup information from JAXBElement

From: Wolfgang Laun <wolfgang.laun_at_gmail.com>
Date: Wed, 30 Sep 2009 19:51:13 +0200

<gulp/>

Just to state the obvious, repeating what I think I've understood:

xs:anyType results in an org.w3c.dom.Element e, which can be unmarshalled
(provided we have the JAXB generated "bar" classes) with an Unmarshaller
derived from a context created from a suitable package or class set. (You
want to know is whether this Element has been substituted for
_GenericExtensionTypeA or _...B but both of these are optional; the only
chance is to obtain the information contained in some "bar" environment.)

My train of thoughts:
   - Unmarshalling Element e and using getValue() will tell you the class
and its package, and the tag ("tag").
   - In this package's ObjectFactory should be a method createTag, returning
a JAXBElement<?>.
   - Retrieving annontation @XmlElementDecl from method createTag should
give you, in its field substitutionHeadName, the name of the element from
foo:A.

Note that this is all rather iffy, based on some unrelated case studies I've
lying around.

-W

On Wed, Sep 30, 2009 at 5:52 PM, Claus Nagel <claus.nagel_at_gmail.com> wrote:

> 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
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>
>