users@jaxb.java.net

RE: Setting one element into another element with the same type

From: Franklin, Brian <brian.franklin_at_ciraden.com>
Date: Wed, 27 Aug 2003 16:43:37 -0400

Joe, sorry for the delay in response.

It is my feeling that no decent solution for these issues can be found
without using type substitution. Regarding your example, I would say that
you would use neither the B nor C element name--you would leave the element
named A with an xsi:type="Derived" attribute.

Let me take this opportunity to discuss the way that type instances are
marshalled by themselves (as root content instances). I am pretty sure a
discussion similar to this has come up before, but I'm not exactly sure what
its purpose or solution was. Please bear with me.

Let's say you have the following schema fragment:

        <complexType name="Container">
                <sequence>
                        <element name="InnerElement" type="int" />
                </sequence>
        </complexType>

And that in your code you do this:

        ...
        Container c = objectFactory.createContainer();
        c.setInnerElement(5);
        marshaller.marshal( c, output );
        ...

You will only get the contents of Container without the container tag, like
this:

        <InnerElement>5</InnerElement>

While this may actually be required by the XML Schema / XML instance
document standards (not sure), you unfortunately lose the identity of this
instance. I think that you should instead get output like this:

        <Container>
                <InnerElement>5</InnerElement>
        </Container>

In analogy to Java code, this would be as if

        marshaller.marshal( new HashMap() );

and

        Map myMap = new HashMap();
        marshaller.marshal( myMap );

yielded different marshalled outputs. This seems flawed.


Thanks, as always, for your time.

Brian Franklin


-----Original Message-----
From: Joseph Fialli [mailto:joseph.fialli_at_sun.com]
Sent: Thursday, August 21, 2003 4:31 PM
To: users_at_jaxb.dev.java.net
Subject: Re: Setting one element into another element with the same type




Brian Franklin wrote:

> Ok, I have now realized that it will only automatically wrap the type
> in an element if it's directly that type, and not a child type, which
> makes sense. But that's now back to being quite unfortunate.

Thanks for this usability feedback. Since element substitution is
experimentally supported in JAXB 1.0.1
standard implementation, there is time to consider how this should be
specified in JAXB 2.0.

Would you prefer that the implementation non-deterministically compute a
possible element name if
only the element's value is provided to the JAXB property setter
representing an element substitution
group.

For example, if one has elements A, B and C in an element substutition
group and element A has
XML type Base and elements B and C have XML type Derived, which derives
by extension from Base,
calling the property setter with a Java instance of a type matching
"Derived", it would be ambiguous whether
the element name should be B or C.

It is a difficult trade off to determine whether :
1. to non-deterministically do something that is a validbut potentially
suprising
2. giving immediate feedback that the element name is not provided(via
an exception)
3. optional feedback (via Validation of the content) that the property
is not set with
    enough info to determine an element name. (here's hoping that
validation flags this case)

-Joe
 

>
>
> Sorry for having a conversation with myself.
>
> I would like to reiterate my request for an expeditious release of the
> JAXB RI with type substitution support. 8-}
>
> Brian Franklin
>
>
> On Wednesday, August 20, 2003, at 10:01 PM, Brian Franklin wrote:
>
>> Never mind about the "trade-off" comment. I did a quick test, and I
>> see that it automatically wraps the type in an element with the
>> referenced element's name. That's quite fortunate.
>>
>> Brian Franklin
>>
>>
>> On Wednesday, August 20, 2003, at 05:32 PM, Franklin, Brian wrote:
>>
>>> Thanks for the excellent information.
>>>
>>> We actually have been using element substitution. I was reluctant
>>> to use it
>>> in a particular situation because it normally affects the generated
>>> method
>>> name, but I had forgotten about using a property name customization to
>>> override it. Also, because of the loss of functionality mentioned
>>> below.
>>>
>>> So, for anyone else who is reading and doesn't follow, this is a
>>> possible
>>> workaround for the situation:
>>>
>>> New schema fragment:
>>> (Compile with -extension argument for command line or extension="true"
>>> attribute for Ant task.)
>>>
>>> <complexType name="SomeType">
>>> <sequence>
>>> <element name="Something" type="int" />
>>> </sequence>
>>> </complexType>
>>> <element name="SomeElement" type="this:SomeType" />
>>>
>>> <element name="Container">
>>> <complexType>
>>> <sequence>
>>> <element ref="this:SomeElement">
>>> <annotation><appinfo>
>>> <!-- Without this your
>>> method name would be getSomeElement() instead of getInnerElement() -->
>>> <jaxb:property
>>> name="InnerElement" />
>>> </appinfo></annotation>
>>> </sequence>
>>> </complexType>
>>> </element>
>>>
>>>
>>> The only down side to this, if I'm not mistaken is that you can no
>>> longer do
>>> the following, which you could do previously:
>>>
>>> SomeType someType = objFact.createSomeType();
>>> someType.setSomething(5);
>>> Container container = objFact.createContainer();
>>> container.setInnerElement( someType );
>>>
>>> So, it seems to currently be a trade-off until the new spec comes out.
>>>
>>> Joe, if I misunderstood what you were saying, am wrong in any of the
>>> examples, or if there is a better way to do this, please let me know.
>>>
>>> Thanks again,
>>> Brian Franklin
>>>
>>> -----Original Message-----
>>> From: Joseph Fialli [mailto:joseph.fialli_at_sun.com]
>>> Sent: Wednesday, August 20, 2003 4:16 PM
>>> To: users_at_jaxb.dev.java.net
>>> Subject: Re: Setting one element into another element with the same
>>> type
>>>
>>>
>>>
>>>
>>> Franklin, Brian wrote:
>>>
>>>> I believe this issue (or at least one similar to it) has been
>>>> brought up in
>>>> previous threads (1), but I wanted to confirm something and ask the
>>>> team
>>>
>>> how
>>>
>>>> this will work in the future. Questions are near the bottom.
>>>>
>>>> Kohsuke gave a pretty simple example previously that I *think* is
>>>> the same
>>>> thing, but just to be sure, here's an example that I know behaves
>>>
>>> strangely.
>>>
>>>>
>>>> Schema fragment:
>>>> <complexType name="SomeType">
>>>> <sequence>
>>>> <element name="Something" type="int" />
>>>> </sequence>
>>>> </complexType>
>>>> <element name="SomeElement" type="this:SomeType" />
>>>>
>>>> <element name="Container">
>>>> <complexType>
>>>> <sequence>
>>>> <element name="InnerElement"
>>>> type="this:SomeType" />
>>>> </sequence>
>>>> </complexType>
>>>> </element>
>>>>
>>>> Sample code fragment:
>>>>
>>>> SomeType someType = objFact.createSomeElement();
>>>> someType.setSomething(5);
>>>>
>>>> Container container = objFact.createContainer();
>>>> container.setInnerElement( someType );
>>>>
>>>> marshaller.marshal( ...output... );
>>>>
>>>> Resulting output fragment:
>>>>
>>>> <Container>
>>>> <InnerElement>
>>>> <SomeElement>
>>>> <Something>5</Something>
>>>> </SomeElement>
>>>> </InnerElement>
>>>> </Container>
>>>>
>>>>
>>>> Questions:
>>>>
>>>> 1) Is this how this will behave in the future?
>>>>
>>> The JAXB 1.0 Specification definitely does not specify this marshalled
>>> behavior.
>>> You are observing a behavior in the current implementation.
>>>
>>> The JAXB property setter method definitely allows for an instance of
>>> javax.xml.bind.Element to be
>>> set on a JAXB property, this behavior was necessary to support a JAXB
>>> property representing
>>> a wildcard <xsd:any>, or in the future, to support element substitution
>>> groups. Both these
>>> cases required the JAXB setter to be able to dynamically provide an
>>> element name to use for validation and marshalling.
>>>
>>> The example above demonstrates when the schema has a fixed element name
>>> for the JAXB
>>> property InnerElement representing a local child element
>>> AND the application also dynamically provides an element name by
>>> calling
>>> the JAXB setter property for InnerElement with an instance of
>>> javax.xml.bind.Element.
>>>
>>> We plan to address this hole in the JAXB 1.0 Specification that you
>>> have
>>> pointed out
>>> (we have been aware of it) and identify a user-friendly, deterministic
>>> solution in
>>> the JAXB 2.0 expert group.
>>>
>>>> 2) Will the inclusion of type substitution change how this
>>>> looks/behaves?
>>>>
>>>>
>>> Type substitution does not allow for an element name to be changed for
>>> JAXB property.
>>>
>>> Actually, element substitution group support is the interesting feature
>>> where a JAXB setter
>>> can take as a parameter an element instance with an element name
>>> different than is specified in the
>>> constraining schema AND the setter provided element name REPLACES the
>>> schema element reference.
>>> This support is already implemented in JAXB 1.0.1 with xjc -extension
>>> mode and it
>>> does not suffer from the issue that your case identifies. For this
>>> case, the implementation
>>> is always allowing the element name provided by the JAXB setter to
>>> override
>>> the schema reference to the element substitution group header element,
>>> thus, both
>>> element names are not output by the marshaller.
>>>
>>>> 3) If the ability to "T getType()" and "setType(T)" of an element is
>>>> implemented in the future, will this be handled automatically in
>>>> this case?
>>>>
>>>
>>> Automatically handling this case or throwing an exception when the JAXB
>>> setter
>>> method is called with a javax.xml.bind.Element instance are two
>>> possible
>>> solutions.
>>> If the automated handling can not be deterministically specified,
>>> throwing an
>>> exception would be the preferable path.
>>>
>>>
>>> Thanks for your feedback.
>>>
>>> -Joe
>>>
>>>> 4) If this is going to continue to behave this way, shouldn't
>>>> setting an
>>>> Element into another Element field of the same type throw an
>>>> exception or
>>>> something?
>>>>
>>>>
>>>
>>>> Thanks, as always, for your time and hard work.
>>>>
>>>>
>>>
>>>> Brian Franklin
>>>>
>>>> ----
>>>> Footnotes: (following the trend that Ryan seems to be pushing)
>>>>
>>>> (1) For those of you who want to search the archives, the following
>>>> topics
>>>> seemed to be at least somewhat relevant to the issue:
>>>> "Marshalling a content sub-tree"
>>>> "Help!! Elements & types"
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> 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
>>>
>>> ---------------------------------------------------------------------
>>> 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
>
>
>
> ---------------------------------------------------------------------
> 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

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
For additional commands, e-mail: users-help_at_jaxb.dev.java.net