Title: RE: [castor-dev] Unmarshalling unknown java

My application is such that we have defined a generic
request element (i.e. the container) that carries data
common to all requests (e.g. request header info).  It
then may hold one of 33 specific request types (i.e.
the members).  In a pure Java situation, one would
probably use inheritance to define this relationship.
However, I could not get Castor to implement an inher-
ited class relationship.  Rather, it creates a class
structure that employs containership as I described. 
(If anybody knows a way to do this, I'd love to hear it--
stop me before I kill again!)  Given this, the problem
is not so much testing the Object.  It's more a case
of determining which object to test.

I agree that it would be very nice to simply ask the
container to provide a reference to the non-null contained
member.  It just doesn't exist in the generated code.

Pete

-----Original Message-----
From: S.H.Kinder [mailto:[EMAIL PROTECTED]]
Sent: Thursday, November 15, 2001 9:42 AM
To: [EMAIL PROTECTED]
Subject: Re: [castor-dev] Unmarshalling unknown java


Pete

Thanks for the reply. This is one way I hadn't thought of
yet. It would require a change to our XML. It doesn't
seem quite right to have to construct the XML in this way
to get round a castor problem. Is it a castor problem?
I was hoping that it would be possible to simply test
the Object that had been unmarhalled and use it accordingly
e.g. something like your second method or instanceof.

Do I take it from your wrapping in this way that you
tried the above and couldn't get it to work? I can't see
a way to unmarshal right now without giving it an
explicit class type

e.g.

CollectStart cs =
(CollectStart) Unmarshaller.unmarshal(CollectStart.class, reader);

I suspect an answer may lie in mapping but not too
sure there either.

Cheers

Steve

Pete Lane wrote:
>
> Steve,
>
> I've had to address a problem similar, if not identical,
> to what you are describing.  I have a schema that defines
> an element which, in turn, contains instances of other
> elements.  In any given XML instance document I know that
> exactly one of these "contained" elements will be populated.
> The schema looks something like:
>
> <element name="container">
>  <complexType>
>   <sequence>
>    <element name="member1" type="someType1" minOccurs="0"/>
>    <element name="member2" type="someType2" minOccurs="0"/>
>    .             .              .            .         .
>    <element name="memberN" type="someTypeN" minOccurs="0"/>
>   </sequence>
>  </complexType>
> <element>
>
> What I'm really trying to define here is a <choice> relationship,
> but I have not been able to get <choice> in Castor to work
> properly.  Hence, I've resorted to appending minOccurs="0" to
> all the contained elements-- not the same effect as <choice>,
> but close enough (at least for my purposes).
>
> So, once you have unmarshalled an XML instance, how do you determine
> which "contained" element is actually populated.  The key is to
> examine the object tree that Castor creates from the XML.  What you
> end up with is a Container object that holds private member
> references that represent each of the contained elements-- Member1,
> Member2, ...MemberN.  It also provides a "getter" method for each
> of these.  Given this arrangement you could simply have a big
> if statement such as:
>
> String getContainedElementName(Container c)
> {
>   Object res = null;
>   if ((res = c.getMember1()) != null)
>     return res.getClass().getName();
>   else if ((res = c.getMember2()) != null)
>     return res.getClass().getName();
>   .    .      .       .       .    .
>   else if ((res = c.getMemberN()) != null)
>     return res.getClass().getName();
>   else
>     return res;
> }
>
> But this is pretty ugly.  Plus, if you ever want
> to add/modify/delete any "contained" elements, you've
> got to modify the code as well.
>
> A better approach, at least from the standpoint of
> maintenance, is to use reflection to query the container
> object for all of its "getter" methods.  Then invoke each
> in turn until you get a non-null result:
>
> String getContainedElementName(Container c)
> {
>   Class cl = c.getClass();
>   Method[] meths = cl.getMethods();
>   String mName = new String("");
>   try
>   {
>     for (int i = 0; i < meths.length; i++)
>     {
>       mName = meths[i].getName();
>       if (mName.startsWith("get"))
>       {
>         Object o = meths[i].invoke(c, null);
>         if (o != null)
>           return o.getClass().getName();
>       }
>     }
>   }
>   catch (Exception e)
>   {
>     // invoke() may throw one of several exceptions
>   }
>   return null;
> }
>
> This approach frees you from the burden of keeping the
> Java code in-sync with the schema.  The downside is that
> the reflection is somewhat expensive.  How much so depends
> to a large extent on the quantity of "contained" elements
> you're dealing with.  I'd sure like to hear about other
> approaches folks on this list may have employed.
>
> Hope this helps.
>
> Regards,
>
> Pete
>
> -----Original Message-----
> From: S.H.Kinder [mailto:[EMAIL PROTECTED]]
> Sent: Wednesday, November 14, 2001 6:32 PM
> To: [EMAIL PROTECTED]
> Subject: [castor-dev] Unmarshalling unknown java
>
> Apologies if this is off the development thread or a dumb question. I'm
> new to castor and am investigating whether it can do the job for me.
> It seems a good way to extract data from xml in principle.
>
> I have succeeded in defining some simple xml and schema to allow me
> to unmarshal a known object type from the xml. However what if the xml
> might define one of a list of possible java objects, defined via the
> schema. How can I unmarshal into a java Object, so that I can then
> test the Object class and act accordingly? If someone could provide
> an example and/or advice this would be much appreciated.
>
> Cheers
>
> Steve
>
> -----------------------------------------------------------
> If you wish to unsubscribe from this mailing, send mail to
> [EMAIL PROTECTED] with a subject of:
>         unsubscribe castor-dev

-----------------------------------------------------------
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
        unsubscribe castor-dev

Reply via email to