Menu

#17 Dingo doesn't distinguish between nill and not present

open
nobody
None
5
2008-10-01
2008-10-01
Nathan
No

Hi.

If you have a schema which has nillable=true and minOccurs = 0 on an element, the classes which dingo generates cannot distinguish between the element simply not being present vs. the element being set to nil. (xsd.exe has the same problem). I have a schema in which the semantic difference between an element not being present vs being set to nil is quite large and important.

The .NET XMLSerializer recognizes the PropertyNameSpecified pattern which could be used to fix this.

Discussion

  • Peter Lin

    Peter Lin - 2008-10-09

    sorry for the delay responding. can you post an example of the schema and I'll take a look.

    thanks

    peter

     
  • Peter Lin

    Peter Lin - 2008-10-23

    thanks, I will take a look tonight. thanks for being patient and understanding.

    peter

     
  • Peter Lin

    Peter Lin - 2008-10-24

    I just tried nillable with the current code in SVN and it appears to work correctly. Here is what I get for a test schema.

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema targetNamespace="geneology" xmlns="test" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="personType" abstract="false">
    <xs:sequence>
    <xs:element name="firstName" type="xs:string"/>
    <xs:element name="middleName" type="xs:string" nillable="true"/>
    <xs:element name="lastName" type="xs:string" nillable="true"/>
    <xs:element name="maidenName" type="xs:string"/>
    <xs:element name="dateOfBirth" type="xs:date"/>
    <xs:element name="dateOfDeath" type="xs:dateTime"/>
    <xs:element name="gender" type="xs:string"/>
    <xs:element name="spouse" type="personType" maxOccurs="unbounded"/>
    <xs:element name="child" type="personType" maxOccurs="unbounded"/>
    </xs:sequence>
    </xs:complexType>
    <xs:element name="geneology" type="geneologyType"/>
    <xs:complexType name="geneologyType">
    <xs:sequence>
    <xs:element name="Person" type="personType" maxOccurs="unbounded"/>
    </xs:sequence>
    </xs:complexType>
    </xs:schema>

    the nillable properties should have "?", which it does.

    using System;
    using System.Xml.Serialization;

    namespace geneology
    {
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="geneology")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="geneology",IsNullable=false)]
    public class PersonType
    {
    #region fields
    [System.Xml.Serialization.XmlElementAttribute("firstName")]
    public string firstName;
    [System.Xml.Serialization.XmlElementAttribute("middleName")]
    public string? middleName;
    [System.Xml.Serialization.XmlElementAttribute("lastName")]
    public string? lastName;
    [System.Xml.Serialization.XmlElementAttribute("maidenName")]
    public string maidenName;
    [System.Xml.Serialization.XmlElementAttribute("dateOfBirth")]
    public DateTime dateOfBirth;
    [System.Xml.Serialization.XmlElementAttribute("dateOfDeath")]
    public DateTime dateOfDeath;
    [System.Xml.Serialization.XmlElementAttribute("gender")]
    public string gender;
    [System.Xml.Serialization.XmlElementAttribute("spouse",typeof(personType))]
    public personType[] spouse;
    [System.Xml.Serialization.XmlElementAttribute("child",typeof(personType))]
    public personType[] child;
    #endregion

    public PersonType()
    {
    }
    #region properties

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public string FirstName
    {
    get { return firstName; }
    set { this.firstName = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public string MiddleName
    {
    get { return middleName; }
    set { this.middleName = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public string LastName
    {
    get { return lastName; }
    set { this.lastName = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public string MaidenName
    {
    get { return maidenName; }
    set { this.maidenName = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public DateTime DateOfBirth
    {
    get { return dateOfBirth; }
    set { this.dateOfBirth = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public DateTime DateOfDeath
    {
    get { return dateOfDeath; }
    set { this.dateOfDeath = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public string Gender
    {
    get { return gender; }
    set { this.gender = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public personType[] Spouse
    {
    get { return spouse; }
    set { this.spouse = value; }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public personType[] Child
    {
    get { return child; }
    set { this.child = value; }
    }
    #endregion

    #region methods

    public string getFirstName()
    {
    return firstName;
    }

    public void setFirstName(string param)
    {
    firstName = param;
    }

    public string getMiddleName()
    {
    return middleName;
    }

    public void setMiddleName(string param)
    {
    middleName = param;
    }

    public string getLastName()
    {
    return lastName;
    }

    public void setLastName(string param)
    {
    lastName = param;
    }

    public string getMaidenName()
    {
    return maidenName;
    }

    public void setMaidenName(string param)
    {
    maidenName = param;
    }

    public DateTime getDateOfBirth()
    {
    return dateOfBirth;
    }

    public void setDateOfBirth(DateTime param)
    {
    dateOfBirth = param;
    }

    public DateTime getDateOfDeath()
    {
    return dateOfDeath;
    }

    public void setDateOfDeath(DateTime param)
    {
    dateOfDeath = param;
    }

    public string getGender()
    {
    return gender;
    }

    public void setGender(string param)
    {
    gender = param;
    }

    public personType[] getSpouse()
    {
    return spouse;
    }

    public void setSpouse(personType[] param)
    {
    spouse = param;
    }

    public personType[] getChild()
    {
    return child;
    }

    public void setChild(personType[] param)
    {
    child = param;
    }
    #endregion
    }
    }

    I'm wondering if it's the namespace that causing the issue. Is it this element that was giving you trouble?

    <xs:complexType name="NameType">
    <xs:sequence>
    <xs:element name="FirstName" minOccurs="0">
    <xs:simpleType>
    <xs:restriction base="core:FirstNameType">
    <xs:maxLength value="12"/>
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    <xs:element name="MiddleInitial" type="core:MiddleInitialType" nillable="true" minOccurs="0"/>
    <xs:element name="LastName" type="core:LastNameType" minOccurs="0"/>
    </xs:sequence>
    </xs:complexType>

    I'll try to isolate that and run a test against it. might take me a day or two.

    peter

     
  • Nobody/Anonymous

    oh wait, I just realized I missed the minOccurs=0.

    please ignore the previous email, duh on my part.

    peter

     
  • Nobody/Anonymous

    I've confirmed the bug. I should be able to fix it this weekend.

    thanks for reporting it.

    peter

     
  • Peter Lin

    Peter Lin - 2008-10-24

    I just checked in a new executable to SVN. I'll try to post a new release on saturday. if you're in a rush, please give the version in SVN a try.

    thanks

    peter

     

Log in to post a comment.