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