18

I have been using xsd.exe to generate a class for deserializing XML into. I have decimal value in the source xsd that is not required:

<xs:attribute name="Balance" type="xs:decimal" use="optional" />

The resulting class from xsd generates the following code:

private decimal balanceField;

[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal Balance {
    get {
        return this.balanceField;
    }
    set {
        this.balanceField = value;
    }
}

Which I note is not nullable.

How do I instead generate the field as nullable, illustrated as follows:

private decimal? balanceField;

[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal? Balance {
    get {
        return this.balanceField;
    }
    set {
        this.balanceField = value;
    }
}
Abel
  • 56,041
  • 24
  • 146
  • 247
Don Vince
  • 1,282
  • 3
  • 18
  • 28

3 Answers3

7

Currently it works as it should. I'm using xsd v2.0.50727.42 and:

<xs:element name="Port" type="xs:int" nillable="true" />

generates exactly what you've been looking for (without redundant ...Specified field and property):

private System.Nullable<int> portField;

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true)]
public System.Nullable<int> Port {
    get {
        return this.portField;
    }
    set {
        this.portField = value;
    }
}
Michał Powaga
  • 22,561
  • 8
  • 51
  • 62
  • 10
    That only works for elements, not for attributes as the question originally asked. – James Skimming Jul 10 '13 at 09:17
  • That works by coincidence because minOccurs has a default value of 1 If you change it to minOccurs="0", you have to have the IsPortSpecified to force the null to show up. – JJS Jan 23 '19 at 22:36
4

I believe if you add nillable="true" in your XML schema definition, XSD will create a nullable type for that element. This is probably a good idea anyway, since you are implying that this value is indeed nillable and this would make your schema definition more explicit in that regard.

Unfortunately, it still includes the corresponding "Specified" field in this case. If you want the serializer to obey the nullable value directly, you will need to manually remove the "xxSpecified" column from the generated code.

mtazva
  • 1,005
  • 9
  • 13
3

I've just noticed that it has actually included the following code:

private bool balanceFieldSpecified;

[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool BalanceSpecified {
    get {
        return this.balanceFieldSpecified;
    }
    set {
        this.balanceFieldSpecified = value;
    }
}

Which provides the functionality I need.

I'll leave the question open for a while in case there is an elegant way to make use of nullable? type instead.

Don Vince
  • 1,282
  • 3
  • 18
  • 28
  • 11
    Unfortunately, xsd.exe was around way before nullable types existing in the .NET framework, so they had to come up with a solution that works in any case. I'm not aware of any way to tell xsd.exe to use nullable types instead..... (somebody ought to step up and create a useful alternative to xsd.exe some day! :-) ) – marc_s Sep 14 '09 at 12:06
  • A similar kludge exists for xsd.exe generated DataSets, except that instead of a property, the row will contain an `IsBalanceNull()` method. – Dan Is Fiddling By Firelight Dec 11 '09 at 19:08