1

I have and xsd file that contains a enumerated type with options of 1 or 2. This is an extract of the file that contains the enum type CompanyCode

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
     elementFormDefault="qualified"
     attributeFormDefault="unqualified">

     <xs:element name="HOST">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Header" type="Header" minOccurs="0"/>
                <xs:element name="MLC" minOccurs="0">
                  <xs:complexType>
                    <xs:sequence>
                      <xs:element name="MLCCommodity" type="MLCCommodity" maxOccurs="unbounded"/>
                    </xs:sequence>
                  </xs:complexType>
                </xs:element>
                <xs:element name="Departments" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Department" type="Department" maxOccurs="unbounded"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="Type">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:length value="1"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>

    <xs:simpleType name="CompanyCode">
      <xs:restriction base="xs:nonNegativeInteger">
        <xs:totalDigits value="1"/>
        <xs:pattern value="\d"/>
        <xs:enumeration value="1"/>
        <xs:enumeration value="2"/>
      </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="IDType">
        <xs:restriction base="xs:string">
            <xs:minLength value="5"/>
            <xs:maxLength value="8"/>
            <xs:pattern value="\d{5}"/>
            <xs:pattern value="\d{8}"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="HostAction">
        <xs:restriction base="xs:string">
            <xs:length value="1"/>
            <xs:enumeration value="D"/>
            <xs:enumeration value="I"/>
            <xs:enumeration value="U"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="BusinessPillar">
        <xs:restriction base="xs:string">
            <xs:length value="3"/>
            <xs:enumeration value="ALM"/>
            <xs:enumeration value="CCC"/>
            <xs:enumeration value="CSD"/>
            <xs:enumeration value="CWD"/>
            <xs:enumeration value="IGA"/>
            <xs:enumeration value="TAS"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="Header">
        <xs:sequence>
            <xs:element name="IDCode">
                <xs:complexType>
                    <xs:simpleContent>
                        <xs:extension base="IDType">
                            <xs:attribute name="Type" use="required">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:length value="1"/>
                                        <xs:enumeration value="C"/>
                                        <xs:enumeration value="I"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:attribute>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
            </xs:element>
            <xs:element name="CreationDate" type="xs:dateTime"/>
            <xs:element name="Version">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:length value="5"/>
                        <xs:pattern value="\d\.\d\.\d"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="PricingZone" minOccurs="0">
                <xs:simpleType>
                    <xs:restriction base="xs:integer">
                        <xs:totalDigits value="2"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="Business" type="BusinessPillar" minOccurs="0"/>
            <xs:element name="State">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="2"/>
                        <xs:maxLength value="3"/>
                        <xs:enumeration value="ACT"/>
                        <xs:enumeration value="NSW"/>
                        <xs:enumeration value="NT"/>
                        <xs:enumeration value="NZ"/>
                        <xs:enumeration value="QLD"/>
                        <xs:enumeration value="SA"/>
                        <xs:enumeration value="TAS"/>
                        <xs:enumeration value="VIC"/>
                        <xs:enumeration value="WA"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="MLCCommodity">
      <xs:sequence>
        <xs:element name="Description" minOccurs="0">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:minLength value="1"/>
              <xs:maxLength value="40"/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
      </xs:sequence>
      <xs:attribute name="Number" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:length value="3"/>
            <xs:pattern value="\d{3}"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="CompanyCode" type="CompanyCode" use="required"/>
      <xs:attribute name="Action" type="HostAction" use="required"/>
    </xs:complexType>

    <xs:complexType name="Department">
        <xs:sequence>
            <xs:element name="Description" minOccurs="0">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="1"/>
                        <xs:maxLength value="40"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="DepartmentNumber" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:length value="2"/>
                    <xs:pattern value="\d{2}"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="Action" type="HostAction" use="required"/>
    </xs:complexType>
</xs:schema>

Running this file through xsd.exe /c test.xsd gives me a c# file that contains this code for the definition of the CompanyCode enum.

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
public enum CompanyCode {

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("1")]
    Item1,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("2")]
    Item2,
}

Using this, when I read the data from the xml file, the values that come is the string Item1 or Item2, rather than the digits 1 or 2.

Should I just use a switch statement to convert the values to the 1 and 2 that I need to store in the destination, or is there a way I can get the xml file to read the 1 or 2 directly?

A typical record in the xml file looks like this

<ns0:MLCCommodity Number="001" CompanyCode="1" Action="I">
  <ns0:Description>DO NOT USE</ns0:Description>
</ns0:MLCCommodity>

Thanks

Strudo76
  • 15
  • 6
  • Can you please elaborate on the issue? What do you mean by 'when I read the data from the xml file, the values that come is the string Item1 or Item2, rather than the digits 1 or 2'? Come where? Do you receive an exception? Also, I'd much appreciate working repro of the issue with full code listing, xml example and explanation of the expected behavior. – fenixil Dec 02 '19 at 04:18
  • If it is a standard schema I wouldn't recommend changing because it may cause other issues. If you need the integer value you can simply do a cast where you are using the number : (int)code. Or in the opposite direction int myCode = 1; CompanyCode code = (CompanyCode)myCode; – jdweng Dec 02 '19 at 07:08
  • Whoever wrote this schema believes in overkill. Defining an integer type with enumeration (1,2) is surely all you need to say, without also saying that it's a nonNegativeInteger, comprises one digit, and satisfies the pattern \d. That's saying the same thing four times. Do they get paid for coding by the line? – Michael Kay Dec 02 '19 at 08:21
  • @MichaelKay Pretty sure you're right there. I don't know much about xml/xsd, but it looks pretty convoluted to me. I think it might have been automatically generated by XML Spy. – Strudo76 Dec 03 '19 at 07:38
  • @fenixil I'll get something together as an example tomorrow and tag you in a comment when it's ready. – Strudo76 Dec 03 '19 at 07:40
  • @fenixil Shared files [here](https://drive.google.com/open?id=12wz0EpXrZH1V47hWKIPUrgFN4AB2ogtc) We will receive an xml file regularly, that needs to be imported into our POS Firebird DB. The CompanyCode field specified by the XSD file should be either "1" or "2", but I get either "Item1" or "Item2". I can work with the strings, however if the spec changes to add additional CompanyCode values I'd need to modify the code. This is pretty unlikely as the MLC data is legacy data. If there's a better way to achieve the goal, I'm open to suggestions. Thanks – Strudo76 Dec 03 '19 at 23:11

1 Answers1

2

I think you confused commentators by expression 'the values that come is the string Item1 or Item2'. In the example that you shared I can see that your main concern is that you cannot get 'xml value' from enum value:

var mLCCommodity = new MLCCommodity() { CompanyCode = CompanyCode.Item2 };
// below gives you 'Item2', but you just want '2'
var value = mLCCommodity.CompanyCode.ToString();

I see several ways to achieve what you need:

1. Quick, simple but risky

I checked that xsd.exe generates enum entries by convention appending xml value to the end of the enum entry so you can just remove Item from the value:

var quickCompanyCodeName = mLCCommodity.CompanyCode.ToString().Replace("Item",string.Empty);
Console.WriteLine(quickCompanyCodeName);

2. Slow, complex but less risky

You can read attribute from the enum item and get it's value. You still rely on the xsd.exe internals implying that it will always mark enum entries with this attribute, but I think that is much less risky than rely on the enum name construction convention. I used this answer to get attribute value:

var enumType = typeof(CompanyCode);
var memberInfos = enumType.GetMember(mLCCommodity.CompanyCode.ToString());
var enumValueMemberInfo = memberInfos.FirstOrDefault(m => m.DeclaringType == enumType);
var valueAttributes = enumValueMemberInfo.GetCustomAttributes(typeof(XmlEnumAttribute), false);
var companyCodeName = ((XmlEnumAttribute)valueAttributes[0]).Name;
Console.WriteLine(companyCodeName);
fenixil
  • 2,106
  • 7
  • 13
  • I think I'll go with option 2. Does exactly what I need. The speed and complexity won't be an issue as it will be rarely (if ever) that the MLC Commodity information is modified. I rather have less risk. Thanks for your answer! – Strudo76 Dec 06 '19 at 01:35