4

The absence of a datum in XML can be expressed either by omitting the element (minOccurs="0" in schema) or by setting it to xsi:nil="true" (nillable=true in schema).

Using minOccurs=0 seem altogether cleaner and more consistent, and it doesn't require the XML to reference the XSD namespace. So what is the benefit of nillable?

3 Answers 3

5

nillable is in the spec because the XML Schema WG had a number of members who saw the world in SQL terms and wanted an explicit equivalent to SQL's null values. It's totally unnecessary in my view: just ignore it and don't use it.

5
  • 2
    When nillable="true" is useful : ibm.com/developerworks/library/ws-tip-null/#N100FA
    – Laiv
    May 15, 2017 at 10:03
  • 2
    @Laiv: You could just as well represent it as <elem><nil /></elem>. But I can see how xsd:nil makes sense in a certain way of thinking, since you can have data types orthogonal to the structure of the XML.
    – JacquesB
    May 15, 2017 at 13:26
  • 1
    If you know that someone has four sons and you don't know the name of the third son, then one way of representing it is <son>Matthew</son><son>Mark</son><son/><son>John</son>. But in general, if you want to model "partial information", then I think you usually want to record something about it, e.g. "unknown" or "not applicable" or "deleted". Invent your own vocabulary to fit the semantics of your particular data. May 15, 2017 at 16:35
  • @MichaelKay Look at my answer softwareengineering.stackexchange.com/a/421094/105827 for a reasonable use of nillable="true" Jan 19, 2021 at 11:06
  • 3
    To me it seems odd to design your XML structure to optimise the way that one particular software package (JAXB) is going to process it. The XML design should be based on the data model alone, not on the quirks of the tools you have chosen to manipulate the XML. Jan 19, 2021 at 11:11
3

I found a use case!

(See https://stackoverflow.com/a/18984458/2886891 for detailed explanation of the bacground.)

When there is a mandatory element in the XSD schema, such as

<xsd:element name="City" type="xsd:string"  minOccurs="1">
<xsd:element name="State" type="xsd:string"  minOccurs="0">

and for some reason I omit to set the value in the class (missing request.setCity("London")), the JAXB Marshaller does not generate the XML element at all.

Unfortunately, the server, instead of complaining about the missing element, returns a completely misleading message:

org.apache.axis2.databinding.ADBException: Unexpected subelement State

Notice that it complains about the presence of the next element, and not about the absence of the mandatory element.

However, if I change the XSD to

<xsd:element name="City" type="xsd:string"  minOccurs="1" nillable="true">
<xsd:element name="State" type="xsd:string"  minOccurs="0">

the marshaller generates

<CardCity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>

which is still invalid, but I get a meaningful error message:

org.apache.axis2.databinding.ADBException: The element: City  cannot be null

Such a message is much more user-friendly and tells me immediately what I did wrong.

1

Unless xs:nil appears in the element tag, many built-in types do not allow empty values. For example,

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="size" type="xs:integer" />
</xs:schema>

then

<size />

would be invalid.

To allow for empty values, a union could be defined:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="size">
        <xs:union>
            <xs:simpleType>
                <xs:restriction base="xs:integer" />
            </xs:simpleType>
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="" />
                </xs:restriction>
            </xs:simpleType>
        </xs:union>
    </xs:element>
</xs:schema>

but this is more cumbersome.

It would probably be better to omit the size element all together, but if you're integrating with another system, that may not be a possibility.

Not the answer you're looking for? Browse other questions tagged or ask your own question.