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