XML Schema nillable=”true” vs minOccurs=”0″

In a WSDL, XML Schema is the section where it define the message format for each operations, which eventually become the real API that users are interested. And it is the most tricky part of the WSDL. Nowadays there are many tools that you can design and use WSDLs without any needs in knowing the meaning of a single line of the WSDL. But there are situations that you may find it is better you have some knowledge in XML Schema section and in WSDL overall.
For this post I m taking a simple example of use of nillable=”true” and minOccurs=”0″. Take the following example.

<xs:element name="myelements">
  <xs:complexType>
    <xs:sequence>
     <xs:element name="nonboth" type="xs:string"/>
      <xs:element minOccurs="0" name="minzero" type="xs:int"/>
      <xs:element name="nilint" nillable="true" type="xs:int"/>
      <xs:element name="nilstring" nillable="true" type="xs:string"/>
      <xs:element minOccurs="0" name="minzeronil" nillable="true" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

Just ignore the meaning of what nillable and minOccurs attributes for now. You can safely say the following XML is valid for the above Schema.

<myelements>
  <nonboth>i can't be either nil nor skipped<nonboth>
  <minzero>3<minzero>
  <nilint><nilint>
  <nilstring>i can have null, but i cant skipeed</nilstring>
  <minzeronil>i can be skipped and have the nil value<minzeronil>
</myelements>

Take the first element ‘nonboth’ in the schema, It has not any minOccurs or nillable attribute. By default minOccurs equal to 1 and nillable equal to false. That mean it can’t have nil value nor it can not be removed from the xml.

Is that making an element nil and removing the element from the XML is same? No. Take the second element in the schema ‘minzerostring’. There you have minOccurs =”0″ but there are no nillable=”true”, mean it is non-nillable. The idea is whenever you don’t want that element in your xml, you can’t have the element keeping empty like

  <minzero xsi:nil="true"><minzero>

But you can remove the whole element from the XML (since it is minOccurs=0).

The opposite of the above scenario is nillable=”true” but minOccurrs != 0. Check the ‘nilint’ element in the schema. There you can’t skip the element ‘nilint’, you have to have the element <nilint/> but it can hold a nil value.

  <nilint xsi:nil="true"></nilint>

or simply

  <nilint xsi:nil="true"/>

Note that the correct way to declare the nil element is,

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

You can understand why when we look at the third element ‘nilstring’. Say you set message the following element

  <nilstring></nilstring>

You can say that this is not nil, this is an empty string. In fact an empty string is nil in some other language, But if we take XML Schema as a language, then for someone to be nil, it have to have the xsi:nil attribute set to “true” or “1”.

So going back to the ‘minzero’ which is non-nillable, by theory you should be able to write the following xml,

  <minzero/>

Since you don’t have that xsi:nil=”1″ this is not a nil value, so the condition nillable=”false” condition is preserved. But unlike for string when you set an empty element for an integer, it doesn’t sound correct. So in practice whenever some schema says non-nillable you should set some valid value.

The last one is ‘minzeronil’ element which is both nillable=”true” and minOccurs=”0″. Whenever you don’t need to set a value for this element, you have the choice of either skipping the element or setting the value of the element to nil. It is obvious rather than setting a nil value it is better you just skip the element to make the XML shorter. This is really needed specially in web services where you need the payload to be minimum as much as possible.

Say you have to prepare the XML and you don’t have valid values for any of the element. So this can be the optimum XML you can create.

<myelements xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
  <nonboth><nonboth>
  <nilint xsi:nil="1"/>
  <nilstring xsi:nil="1">
</myelements>

Read this nice article in developer works on nillable=”true” and minOccurs=”0″ for more.

This entry was posted in web services, WSDL, xml, xml schema and tagged , , , , . Bookmark the permalink.

21 Responses to XML Schema nillable=”true” vs minOccurs=”0″

  1. Aditya says:

    This was very informative. This is a topic of constant confusion in XML. Thanks!

  2. Samuel says:

    It helps me a lot, I’m a newbie in web services and I didn’t even care about the difference between both attributes.

  3. srid says:

    Thanks for the info. You have given a good example and very easy to understand.

  4. Martin says:

    Great blog post, very helpful.

  5. Sabuj Das says:

    Thsi is really helpful. Thanks.

  6. Raichel says:

    This helped a lot. Thanks!

  7. sowmya says:

    Informative.. Thankyou..

  8. Arindam says:

    This is helpful. Can you explain the behavior when the datatype is not a simple one like string,token or int? Say the data type is date or an enumeration you have defined – I have found that the nillable feature is overridden – can you let me know your observations? Thanks

  9. manju851985 says:

    have defined nillable = true in schema. And am trying to give empty string for integer element.

    while say validate in biztalk schema editor its giving error. 😀

    soo am pretty confused with the concept :S

  10. dimuthu says:

    Just giving an empty string is not enough. You may have to declare xsi:nil=”1″ in your element.

    Dimuthu

  11. dimuthu says:

    We are declaring nillable true only on elements, and not on types. Isn’t it?. If so if we extend a simple type (with some restrictions or by an enumerations), we can’t declare it nillable. The element that has the type may be declared as nillable, but not the type itself. This is the first thought came to my mind, I will check and let you know if that is not the case.
    Dimuthu

  12. dtate22 says:

    Excellent article.

  13. Rockmania says:

    Bookmarked this page. Good article.

  14. G says:

    Thanks this helps me out a lot now if only i could figure out how to get my C# web service to use minOccurs=”0″ as apposed to minOccurs=”1″ with out me having to edit the WSDL file after its generated.

  15. SK says:

    Explained ver well, nice article.

  16. Short & Sweet Article which helps me to solve WSDL level validations.

  17. JR says:

    Nice article explaining this subject. I would add to this a discussion of the “default” attribute since for some types (numeric values in particular) this could eliminate confusion if the business rules allow for a default value.
    BTW, the intent of the sample XML matches the schema, however 4 of the elements – nonboth, nilint, minzero and minzeronil – are not closed correctly and would not be considered well formed.
    @G – I believe you can decorate your service method with an attribute defining those conditions.

  18. Pingback: XSD date types with minOccurs set to 0 now has a value of "<xml-fragment…" (nillable defaults to false) | Gravity Layouts

  19. Pingback: XSD date types with minOccurs set to 0 now has a value of "<xml-fragment…" (nillable defaults to false)

  20. RP says:

    Very Nice article. It is explained very well. Thanks for sharing.

  21. Arun Salian says:

    Thanks dude, that was really useful.

Leave a Reply

Your email address will not be published. Required fields are marked *