Retrieving substitutionGroup information from JAXBElement

View: New views
6 Messages — Rating Filter:   Alert me  

Retrieving substitutionGroup information from JAXBElement

by Claus Nagel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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. 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@...
For additional commands, e-mail: users-help@...


Re: Retrieving substitutionGroup information from JAXBElement

by Wolfgang Laun-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Sep 30, 2009 at 10:27 AM, Claus Nagel <claus.nagel@...> 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@...
For additional commands, e-mail: users-help@...



Re: Retrieving substitutionGroup information from JAXBElement

by Claus Nagel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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@...> 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@...
> For additional commands, e-mail: users-help@...
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...


Re: Retrieving substitutionGroup information from JAXBElement

by Wolfgang Laun-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

<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@...> 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@...> 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@...
For additional commands, e-mail: users-help@...




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...



Re: Retrieving substitutionGroup information from JAXBElement

by Claus Nagel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> 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.)

That's exactly my problem. Thanks for your precise summary.

> 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.

Yes, I was afraid this is the way to go... Thank you very much,
Wolfgang. Of course, I prefer using XSOM to query the XML schema
document for the substitutionGroup of some element. However, this
means I have to load the schema into memory prior to parsing the XML
document. There might be situations when this is not feasible: e.g.,
the XML document does not provide a schema location or the schema
location points to somewhere on the network but the parsing client
does not have a network connection.

Given a user provides JAXB mappings for the resulting DOM elements,
the retrieval of the proper substitution group is not dependent on an
XSOM representation of the schema anymore. This is nice as it makes my
API more robust. However, there is a last question that comes to my
mind:

Suppose the user is putting the JAXB mappings into a .jar package (for
example, to easily share his user-defined extensions with someone
else). This means, the ObjectFactory class to be parsed is located
within this .jar file. Does this cause any trouble? I strongly suppose
it does not but as you might have guessed I do not have experience in
that.

Thanks again,
Claus

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...


Re: Retrieving substitutionGroup information from JAXBElement

by Wolfgang Laun-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I know of no reason why reflection or annotation access should not be possible with a class contained in a .jar.
-W

On Thu, Oct 1, 2009 at 9:09 AM, Claus Nagel <claus.nagel@...> wrote:

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.)

That's exactly my problem. Thanks for your precise summary.


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.

Yes, I was afraid this is the way to go... Thank you very much,
Wolfgang. Of course, I prefer using XSOM to query the XML schema
document for the substitutionGroup of some element. However, this
means I have to load the schema into memory prior to parsing the XML
document. There might be situations when this is not feasible: e.g.,
the XML document does not provide a schema location or the schema
location points to somewhere on the network but the parsing client
does not have a network connection.

Given a user provides JAXB mappings for the resulting DOM elements,
the retrieval of the proper substitution group is not dependent on an
XSOM representation of the schema anymore. This is nice as it makes my
API more robust. However, there is a last question that comes to my
mind:

Suppose the user is putting the JAXB mappings into a .jar package (for
example, to easily share his user-defined extensions with someone
else). This means, the ObjectFactory class to be parsed is located
within this .jar file. Does this cause any trouble? I strongly suppose
it does not but as you might have guessed I do not have experience in
that.

Thanks again,

Claus

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...