When using DataContractSerializer with a data member that has IsRequired set to false, the generated schema has minOccurs of 0. However, when using XmlSerializer with an XML element that has IsNullable set to true, the schema has minOccurs of 1. Instead, the schema has nillable set to true. How do I get the XmlSerializer behavior to match DataContractSerializer?

This difference in schema is due to differing ways of representing the lack of a value.

The schema attribute minOccurs is the minimum number of times that the named element must appear for the document to be valid. When minOccurs is 0, then that means it is legal for the element to not appear at all. Therefore, you can represent the lack of a value by omitting the element.

The schema attribute nillable indicates whether the named element can be set to a special nil value that is not in the ordinary range of values for the type of the element. When an element is set to nil, then that means the writer intentionally provided no value. Therefore, you can represent the lack of a value by saying the value is nil.

The DataContractSerializer IsRequired mechanism uses the first approach for representing the lack of a value while the XmlSerializer IsNullable mechanism uses the second approach. However, XmlSerializer also has a way of using the first approach.

The XmlSerializer pattern used to omit an element is to associate the element with a separate Boolean value indicating whether the element should be omitted. The association is done by name like this:

[XmlElement] public string Id;
[XmlIgnore] public bool IdSpecified;

The three requirements for XmlSerializer to make the association are:

  1. The name of the associated field is the same as the element field with the suffix Specified
  2. The associated field is a Boolean value
  3. The associated field is marked XmlIgnore