users@jaxb.java.net

Re: Nillable, minOccurs="0", maxOccurs="unbounded", JAXBElement necessary?

From: Wolfgang Laun <wolfgang.laun_at_gmail.com>
Date: Thu, 3 Jan 2013 10:55:00 +0100

Well, you might have posted this the first time and saved us some time.

(It seems to me that types baz and guz are over-engineered. If you
have an attribute "noValue" for indicating the absence of a value no
matter what is actually there, why have xsi:nil?)

Anyway, here's a workaround. Just (!) for xjc-generating the Java
sources, modify the XML schema: by adding what is commented out in the
snippet below:

<xsd:complexType name="Bar">
  <xsd:sequence>
<!--
     <xsd:choice minOccurs="0" maxOccurs="unbounded">
-->
      <xsd:element name="barname" type="Baz" nillable="true"
minOccurs="0" maxOccurs="unbounded"/>
<!--
      <xsd:element name="doesNotOccur" type="Baz" nillable="true" />
    </xsd:choice>
-->
    <xsd:element name="barname2" type="Guz" nillable="true" minOccurs="0"/>
  </xsd:sequence>
</xsd:complexType>

Also, use this bindings file:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">
  <jaxb:bindings schemaLocation="char.xsd">
    <jaxb:bindings
node="//xsd:complexType[@name='Bar']/xsd:sequence/xsd:choice">
        <jaxb:property name="barname"/>
    </jaxb:bindings>
  </jaxb:bindings>
</jaxb:bindings>

For execution, use the *original* XML schema if you need to use validation
by (un)marshaller.setSchema(.)

This the Java code:
        ObjectFactory objectFactory = new ObjectFactory();
        Bar bar = objectFactory.createBar();

        Baz baz1 = objectFactory.createBaz();
        baz1.setBazname("Value string");
        bar.getBarname().add(objectFactory.createBarBarname(baz1));

        Baz baz2 = objectFactory.createBaz();
        baz2.setBazname("");
        baz2.setNoValue(NoValue.NO_VALUE);
        bar.getBarname().add(objectFactory.createBarBarname(baz2));

        Baz baz3 = objectFactory.createBaz();
        baz3.setNoValue(NoValue.NO_VALUE);
        JAXBElement<Baz> jbebaz3 = objectFactory.createBarBarname(baz3);
        jbebaz3.setNil(true);
        bar.getBarname().add(jbebaz3);
        Guz guz = objectFactory.createGuz();
        guz.setGuzname(null);
        guz.setNoValue(NoValue.NO_VALUE);
        JAXBElement<Guz> barname2 = objectFactory.createBarBarname2(guz);
        barname2.setNil(true);
        bar.setBarname2(barname2);
        JAXBElement<Bar> jbe = objectFactory.createFoo(bar);
        JAXBContext jc = JAXBContext.newInstance( PACKAGE );
        Marshaller m = jc.createMarshaller();
        m.marshal( jbe, new FileOutputStream( XMLOUT ) );

And this is the result:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo>
    <barname>
        <bazname>Value string</bazname>
    </barname>
    <barname noValue="NoValue">
        <bazname></bazname>
    </barname>
    <barname xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
noValue="NoValue" xsi:nil="true"/>
    <barname2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
noValue="NoValue" xsi:nil="true"/>
</foo>

-W


On 01/01/2013, Slappy zd <slapnutcity_at_hotmail.com> wrote:
>
> I see i've taken down some necessary steps in simplifying my example. I'll
> give it another try:
>
> Consider the following XSD:
>
> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
> <xsd:element name="foo" type="bar"/>
> <xsd:complexType name="bar">
> <xsd:sequence>
> <xsd:element name="barname" type="baz" nillable="true"
> minOccurs="0" maxOccurs="unbounded"/>
> <xsd:element name="barname2" type="guz" nillable="true"
> minOccurs="0"/>
> </xsd:sequence>
> </xsd:complexType>
> <xsd:complexType name="baz">
> <xsd:sequence>
> <xsd:element name="bazname" type="xsd:string"/>
> </xsd:sequence>
> <xsd:attribute ref="noValue"/>
> </xsd:complexType>
> <xsd:complexType name="guz">
> <xsd:sequence>
> <xsd:element name="guzname" type="xsd:string"/>
> </xsd:sequence>
> <xsd:attribute ref="noValue"/>
> </xsd:complexType>
> <xsd:attribute name="noValue" type="NoValue"/>
> <xsd:simpleType name="NoValue">
> <xsd:restriction base="xsd:string">
> <xsd:enumeration value="NoValue"/>
> </xsd:restriction>
> </xsd:simpleType>
> </xsd:schema>
>
> Generating classes from this XSD can result in the following setup to create
> an XML file:
>
> ObjectFactory objectFactory = new ObjectFactory();
> Baz baz1 = objectFactory.createBaz();
> baz1.setBazname("Value string");
> Baz baz2 = objectFactory.createBaz();
> baz2.setBazname(null);
> baz2.setNoValue(NoValue.NO_VALUE);
> Bar bar = objectFactory.createBar();
> bar.getBarname().add(baz1);
> bar.getBarname().add(baz2);
> bar.getBarname().add(null);
> Guz guz = objectFactory.createGuz();
> guz.setGuzname(null);
> guz.setNoValue(NoValue.NO_VALUE);
> JAXBElement<Guz> barname2 = objectFactory.createBarBarname2(guz);
> barname2.setNil(true);
> bar.setBarname2(barname2);
> JAXBElement<Bar> foo = objectFactory.createFoo(bar);
>
> JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
>
> Marshaller marshaller = context.createMarshaller();
> marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
> marshaller.marshal(foo, System.out);
>
> The above produces the following XML:
>
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <foo>
> <barname>
> <bazname>Value string</bazname>
> </barname>
> <barname noValue="NoValue"/>
> <barname xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:nil="true"/>
> <barname2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> noValue="NoValue" xsi:nil="true"/>
> </foo>
>
> As you can see, barname2 is filled with xsi:nil="true" and the attribute
> noValue. The same is supposed to be happening to barname when there is no
> value set. The third barname-tag produces the xsi:nil, but it should also
> contain the attribute noValue (again, part of the specification I must use)
> i.e.:
>
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <foo>
> <barname>
> <bazname>Value string</bazname>
> </barname>
> <barname noValue="NoValue"/>
> <barname xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> noValue="NoValue" xsi:nil="true"/>
> <barname2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> noValue="NoValue" xsi:nil="true"/>
> </foo>
>
> Hope this clears somethings up.
>
>> Date: Tue, 1 Jan 2013 13:18:28 +0100
>> Subject: Re: Nillable, minOccurs="0", maxOccurs="unbounded", JAXBElement
>> necessary?
>> From: wolfgang.laun_at_gmail.com
>> To: users_at_jaxb.java.net
>>
>> This XML snippet is not compatible with the XML schema you have posted.
>> -W
>>
>> On 1 January 2013 12:54, Slappy zd <slapnutcity_at_hotmail.com> wrote:
>> > I'm sorry if I haven't been clear. What I mean is, if I have the xsd
>> > i've
>> > given before, the xsi:nil attribute should be generated, but also
>> > another
>> > attribute. I've provided an example below:
>> >
>> > <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>> > <foo>
>> > <bar>Value string</bar>
>> > <bar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>> > xsi:nil="true"
>> > xmlns:baz="http://example.org/baz" baz:noValue="noValue" />
>> > </foo>
>> >
>> > Somewhere I need to insert the attribute "baz:noValue" with the value
>> > "noValue". This is part of the specification I must use, I cannot
>> > change
>> > that. If the attribute "baz:noValue" isn't provided, the message is
>> > incorrect. In the current setup I don't seem to get it to add this
>> > extra
>> > attribute (next to xsi:nil).
>> >
>> >> Date: Tue, 1 Jan 2013 09:48:02 +0100
>> >> Subject: Re: Nillable, minOccurs="0", maxOccurs="unbounded",
>> >> JAXBElement
>> >> necessary?
>> >> From: wolfgang.laun_at_gmail.com
>> >> To: users_at_jaxb.java.net
>> >>
>> >> On 01/01/2013, Slappy zd <slapnutcity_at_hotmail.com> wrote:
>> >> > If a null value is specified, how can I add an attribute with a
>> >> > specific
>> >> > value, "noValue"?
>> >>
>> >> You don't have to add the attribute xsi:nil - it has to be handled by
>> >> the
>> >> marshaller's XML writer.
>> >>
>> >> > It is part of the specification I must follow on which the
>> >> > xsd is based, so I cannot change that. Just nil="true" is not
>> >> > allowed
>> >> > (functionally speaking).
>> >>
>> >> The nil element still needs to be in the XML - otherwise you wouldn't
>> >> be
>> >> aware of it at all. Hence it must contain xsi:nil="true". That's what
>> >> the
>> >> XML schema requires. (Note the 3rd element, a null string, which is
>> >> something else.)
>> >>
>> >> Here's an example:
>> >>
>> >> <xs:element name="doc" type="DocType"/>
>> >> <xs:complexType name="DocType">
>> >> <xs:sequence>
>> >> <xs:element name="Title" type="xs:string" minOccurs="0"/>
>> >> <xs:element name="Tipo" type="xs:string"
>> >> minOccurs="0" maxOccurs="unbounded"
>> >> nillable="true"/>
>> >> </xs:sequence>
>> >> </xs:complexType>
>> >>
>> >> ObjectFactory of = new ObjectFactory();
>> >> DocType doc = of.createDocType();
>> >> JAXBElement<DocType> jbe = of.createDoc( doc );
>> >> doc.setTitle( "The Title" );
>> >> doc.getTipo().add( "Tipo 0" );
>> >> doc.getTipo().add( null );
>> >> doc.getTipo().add( "" );
>> >> doc.getTipo().add( "Tipo 3" );
>> >>
>> >> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>> >> <doc>
>> >> <Title>The Title</Title>
>> >> <Tipo>Tipo 0</Tipo>
>> >> <Tipo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>> >> xsi:nil="true"/>
>> >> <Tipo></Tipo>
>> >> <Tipo>Tipo 3</Tipo>
>> >> </doc>
>> >>
>> >>
>> >>
>> >>
>> >> >
>> >> >> Date: Mon, 31 Dec 2012 17:02:15 +0100
>> >> >> Subject: Re: Nillable, minOccurs="0", maxOccurs="unbounded",
>> >> >> JAXBElement
>> >> >> necessary?
>> >> >> From: wolfgang.laun_at_gmail.com
>> >> >> To: users_at_jaxb.java.net
>> >> >>
>> >> >> Since ArrayList allows null element there's no need for the more
>> >> >> elaborate
>> >> >> JAXBElement. A null List element should result in a
>> >> >> <foo xsi:nil="true"/>
>> >> >>
>> >> >> -W
>> >> >>
>> >> >>
>> >> >> On 31/12/2012, slapnutcity_at_hotmail.com <slapnutcity_at_hotmail.com>
>> >> >> wrote:
>> >> >> > I've got an XSD (a part of a bigger XSD which I do not have
>> >> >> > control
>> >> >> > over), which is provided below.
>> >> >> >
>> >> >> > <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>> >> >> > <xsd:element name="foo">
>> >> >> > <xsd:complexType>
>> >> >> > <xsd:sequence>
>> >> >> > <xsd:element name="bar" type="xsd:string"
>> >> >> > nillable="true" minOccurs="0" maxOccurs="unbounded"/>
>> >> >> > </xsd:sequence>
>> >> >> > </xsd:complexType>
>> >> >> > </xsd:element>
>> >> >> > </xsd:schema>
>> >> >> >
>> >> >> > I has an element "bar" which is of type "string", is nillable,
>> >> >> > does
>> >> >> > not
>> >> >> > have to occur, but it can also occur more than once. I've
>> >> >> > understood
>> >> >> > to
>> >> >> > make a difference between a nillable element and an element not
>> >> >> > provided, a JAXBElement is used.
>> >> >> >
>> >> >> > When I generate classes by using xjc, I get a class Foo with a
>> >> >> > List<String> bar.Isn't it supposed to be
>> >> >> > List<JAXBElement<String>>
>> >> >> > bar?
>> >> >> > If not, how can I make the difference between a value not
>> >> >> > provided
>> >> >> > and
>> >> >> > a nil value? When it is a nil value, it should be able to hold an
>> >> >> > attribute defining it has "noValue" (part of the specification
>> >> >> > I'm
>> >> >> > working with).
>> >> >> >
>> >> >
>