xsd:enumeration restrictions not generated properly when values are not valid identifiers

Feb 17, 2010 at 9:54 PM
Edited Feb 17, 2010 at 10:02 PM

Whenever there is an <xsd:element /> with a <xsd:restrction /> that contains <xsd:enumerations />, they will not be generated properly under certain conditions.  I have included my xsd file along with the generated code to show what I mean.

BTW, I ran ReSharper's "Full Cleanup" on the generated code and modified it ONLY using these steps.

  1. Use automatic properties (this should be a feature)
  2. Removed all "/// <remarks />" lines (this should also be a feature).
  3. Added "Name = " inside XmlEnum lines (NOTE: I did not change the strings generated for the names; I simply prepended "Name = " inside the XmlEnum attribute).

In my opinion, these steps are pretty much required for readability.  Anyway, here are the files:

 


 

Test.xsd:

 

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema id="Test" 
targetNamespace
="http://tempuri.org/Test.xsd"
elementFormDefault
="qualified"
xmlns="http://tempuri.org/Test.xsd"
xmlns:mstns="http://tempuri.org/Test.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> <xsd:complexType name="SomeComplexType"> <xsd:sequence> <xsd:element name="AnEnumeration" maxOccurs="1" minOccurs="0"> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:maxLength value="50" />
<xsd:enumeration value="" />
<xsd:enumeration value="None Selected" /> <xsd:enumeration value="1" /> <xsd:enumeration value="2" /> <xsd:enumeration value="3" /> <xsd:enumeration value="4" /> <xsd:enumeration value="5" /> <xsd:enumeration value="6" /> <xsd:enumeration value="7" /> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:schema>

 

 


 

And here are the 2 (modified in only the ways mentioned above) output files:

SomeComplexType.cs:

 

using System;
using System.CodeDom.Compiler;
using System.ComponentModel;
using System.Diagnostics;
using System.Xml.Serialization;

namespace TestXSD
{
    [GeneratedCode( "System.Xml", "2.0.50727.3082" )]
    [Serializable]
    [DebuggerStepThrough]
    [DesignerCategory( "code" )]
    [XmlType( Namespace = "http://tempuri.org/Test.xsd", TypeName = "SomeComplexType" )]
    [XmlRoot( Namespace = "http://tempuri.org/Test.xsd", IsNullable = true, ElementName = "SomeComplexType" )]
    public class SomeComplexType
    {
        [XmlElement( ElementName = "AnEnumeration" )] public SomeComplexTypeAnEnumeration AnEnumeration { get; set; }
        [XmlIgnore] public bool AnEnumerationSpecified { get; set; }
    }
}

 

 


SomeComplexTypeAnEnumeration.cs

 

 

 
using System;
using System.CodeDom.Compiler;
using System.Xml.Serialization;

namespace TestXSD
{
    [GeneratedCode( "System.Xml", "2.0.50727.3082" )]
    [Serializable]
    [XmlType( AnonymousType = true, Namespace = "http://tempuri.org/Test.xsd", TypeName = "SomeComplexTypeAnEnumeration" )]
    public enum SomeComplexTypeAnEnumeration
    {
        [XmlEnum( Name = "Item" )] Item,
        [XmlEnum( Name = "NoneSelected" )] NoneSelected,
        [XmlEnum( Name = "Item1" )] Item1,
        [XmlEnum( Name = "Item2" )] Item2,
        [XmlEnum( Name = "Item3" )] Item3,
        [XmlEnum( Name = "Item4" )] Item4,
        [XmlEnum( Name = "Item5" )] Item5,
        [XmlEnum( Name = "Item6" )] Item6,
        [XmlEnum( Name = "Item7" )] Item7,
    }
}

 

So, it looks like the generated name of the enumeration (Item, Item1, etc) is also being used in the XmlEnum attribute, which is wrong.  In this case, the XmlEnums should look like this:

 

        [XmlEnum( Name = "" )] Item,
        [XmlEnum( Name = "None Selected" )] NoneSelected,
        [XmlEnum( Name = "1" )] Item1,
        [XmlEnum( Name = "2" )] Item2,
        [XmlEnum( Name = "3" )] Item3,
        [XmlEnum( Name = "4" )] Item4,
        [XmlEnum( Name = "5" )] Item5,
        [XmlEnum( Name = "6" )] Item6,
        [XmlEnum( Name = "7" )] Item7,

 

 


 

Now before anyone says it, I know the XSD is ugly.  However, I have no control over it - it's someone else's webservice - so I have to make due with it.

One solution is to ignore xsd:enumeration restrictions in the generated code.  In this case, instead of an enumeration, there would be no type generated at all for the "AnEnumeration" element - it would simply be a string since xsd:string is its base type.

This is the easiest solution and won't cause errors when the service side decides that they want to add another item (say "8" in our example) without updating the xsd (this happens to me all the time, and it's super annoying).

What do you guys think?

Also, how do I go about contributing to the project (code-wise)?

Thanks,

Chris

(Edited for typos and clarity)

Developer
Feb 18, 2010 at 3:11 PM

Hi Chris,

There is now an update available that should sort this issue out for you. Please give it a try and let me know if you have any problems.

http://wscfblue.codeplex.com/releases/view/40685

Cheers,

Alex.