Click here to Skip to main content
15,910,083 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

In my xsd, the root element is called ruleset which contains a number of rule elements. Each rule element has a selectors element. There can only be one child in this element called 'and', 'or' or selector. Each 'and' or 'or' element must have more than one element which, again, can be an 'and', 'or' or selector.

This second (at least 2) rule applies recursively to all of the operand elements. The xsd compiler didn't like that, so I removed the elements, compiled then added them back in and tried to correct the ruleset.cs classes. I guess I didn't do a very good job:
Error:
<pre>Test method CSRateFactory.Test.UnitTest3.EDF_RuleParser threw exception: 

System.InvalidOperationException: There was an error reflecting type 'RootElementType'. ---> System.InvalidOperationException: There was an error reflecting property 'rule'. ---> System.InvalidOperationException: There was an error reflecting type 'RuleType'. ---> System.InvalidOperationException: There was an error reflecting property 'selectors'. ---> System.InvalidOperationException: There was an error reflecting type 'SelectorsType'. ---> System.InvalidOperationException: There was an error reflecting property 'Item'. ---> System.InvalidOperationException: There was an error reflecting type 'OperandType'. ---> System.InvalidOperationException: There was an error reflecting property 'Items'. ---> System.InvalidOperationException: Type of choice identifier 'ItemElementName' is inconsistent with type of 'Items'. Please use array of ItemChoiceType.


Here is the xsd:
XML
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="RuleSet"
    targetNamespace="http://tempuri.org/RuleSet.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/RuleSet.xsd"
    xmlns:mstns="http://tempuri.org/RuleSet.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>

  <xs:element name="ruleset" type="RootElementType">

  </xs:element>
  <xs:complexType name="RootElementType">
    <xs:sequence>
      <xs:element name="rule" type="RuleType" minOccurs="1" maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="supplierId" type="xs:int" use="required"/>
    <xs:attribute name="validFrom" type="xs:date" use="required"/>
  </xs:complexType>
  
  <xs:complexType name="RuleType">
    <xs:sequence>
      <xs:element name="selectors" type="SelectorsType" minOccurs="0"/>
      <xs:element name="operations" type="OperationsType" minOccurs="0" />
    </xs:sequence>
  </xs:complexType>
  
  <xs:complexType name="OperationsType">
    <xs:sequence>
      <xs:element name="operation" type="OperationType" minOccurs="1" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  
  <xs:complexType name="OperationType">
    <xs:choice>
      <xs:element name="ignore" minOccurs="0" maxOccurs="1" />
      <xs:element name="mappings" type="MappingsType" minOccurs="0" maxOccurs="1" />
    </xs:choice>
  </xs:complexType>
  
  <xs:complexType name="MappingsType">
    <xs:sequence >
      <xs:element name="mapping" type="MappingType" minOccurs="1" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  
  <xs:complexType name="MappingType">
    <xs:sequence >
      <xs:element name="adjustment" type="AdjustmentType" minOccurs="1" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  
  <xs:complexType name="AdjustmentType">
    <xs:attribute name="column" type="xs:string" />
    <xs:attribute name="operation">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="set"/>
          <xs:enumeration value="add"/>
          <xs:enumeration value="prefix"/>
          <xs:enumeration value="postfix"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="value" type="xs:string" />
  </xs:complexType>
  
  <xs:complexType name="SelectorsType">
    <xs:choice>
      <xs:element name="and" type="OperandType"/>
      <xs:element name="or" type="OperandType"/>
      <xs:element name="selector" type="SelectorType"/>
    </xs:choice>
  </xs:complexType>
  
  <xs:complexType name="SelectorType">
    <xs:attribute name="column" type="xs:string" use="required" />
    <xs:attribute name="select">
      <xs:simpleType >
        <xs:restriction base="xs:string">
          <xs:enumeration value="begins-with" />
          <xs:enumeration value="equals" />
          <xs:enumeration value="contains" />
          <xs:enumeration value="ends-with" />
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="value" type="xs:string" use="required" />
  </xs:complexType>
  
  <xs:complexType name="OperandType">
    <xs:choice minOccurs="2" maxOccurs="unbounded" >
      <xs:element name="and" type="OperandType"/>
      <xs:element name="or" type="OperandType"/>
      <xs:element name="selector" type="SelectorType" />
    </xs:choice>
  </xs:complexType>
</xs:schema>


and the class:
C#
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.0.30319.33440.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/RuleSet.xsd")]
[System.Xml.Serialization.XmlRootAttribute("ruleset", Namespace="http://tempuri.org/RuleSet.xsd", IsNullable=false)]
public partial class RootElementType {
    
    private RuleType[] ruleField;
    
    private int supplierIdField;
    
    private System.DateTime validFromField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("rule")]
    public RuleType[] rule {
        get {
            return this.ruleField;
        }
        set {
            this.ruleField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public int supplierId {
        get {
            return this.supplierIdField;
        }
        set {
            this.supplierIdField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="date")]
    public System.DateTime validFrom {
        get {
            return this.validFromField;
        }
        set {
            this.validFromField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/RuleSet.xsd")]
public partial class RuleType {
    
    private SelectorsType selectorsField;
    
    private OperationType[] operationsField;
    
    /// <remarks/>
    public SelectorsType selectors {
        get {
            return this.selectorsField;
        }
        set {
            this.selectorsField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("operation", IsNullable=false)]
    public OperationType[] operations {
        get {
            return this.operationsField;
        }
        set {
            this.operationsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/RuleSet.xsd")]
public partial class SelectorsType {
    
    private object itemField;
    
    private ItemChoiceType itemElementNameField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("and", typeof(OperandType))]
    [System.Xml.Serialization.XmlElementAttribute("or", typeof(OperandType))]
    [System.Xml.Serialization.XmlElementAttribute("selector", typeof(SelectorType))]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
    public object Item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemChoiceType ItemElementName {
        get {
            return this.itemElementNameField;
        }
        set {
            this.itemElementNameField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/RuleSet.xsd")]
public partial class OperandType {

    private object[] itemsField;
    private ItemChoiceType itemElementNameField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("and", typeof(OperandType))]
    [System.Xml.Serialization.XmlElementAttribute("or", typeof(OperandType))]
    [System.Xml.Serialization.XmlElementAttribute("selector", typeof(SelectorType))]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
    public object[] Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemChoiceType ItemElementName
    {
        get
        {
            return this.itemElementNameField;
        }
        set
        {
            this.itemElementNameField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/RuleSet.xsd")]
public partial class SelectorType {
    
    private string columnField;
    
    private SelectorTypeSelect selectField;
    
    private bool selectFieldSpecified;
    
    private string valueField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string column {
        get {
            return this.columnField;
        }
        set {
            this.columnField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public SelectorTypeSelect select {
        get {
            return this.selectField;
        }
        set {
            this.selectField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool selectSpecified {
        get {
            return this.selectFieldSpecified;
        }
        set {
            this.selectFieldSpecified = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://tempuri.org/RuleSet.xsd")]
public enum SelectorTypeSelect {
    
    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("begins-with")]
    beginswith,
    
    /// <remarks/>
    equals,
    
    /// <remarks/>
    contains,
    
    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("ends-with")]
    endswith,
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/RuleSet.xsd")]
public partial class MappingsType {
    
    private AdjustmentType[][] mappingField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("adjustment", typeof(AdjustmentType), IsNullable=false)]
    public AdjustmentType[][] mapping {
        get {
            return this.mappingField;
        }
        set {
            this.mappingField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/RuleSet.xsd")]
public partial class AdjustmentType {
    
    private string columnField;
    
    private AdjustmentTypeOperation operationField;
    
    private bool operationFieldSpecified;
    
    private string valueField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string column {
        get {
            return this.columnField;
        }
        set {
            this.columnField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public AdjustmentTypeOperation operation {
        get {
            return this.operationField;
        }
        set {
            this.operationField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool operationSpecified {
        get {
            return this.operationFieldSpecified;
        }
        set {
            this.operationFieldSpecified = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://tempuri.org/RuleSet.xsd")]
public enum AdjustmentTypeOperation {
    
    /// <remarks/>
    set,
    
    /// <remarks/>
    add,
    
    /// <remarks/>
    prefix,
    
    /// <remarks/>
    postfix,
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/RuleSet.xsd")]
public partial class OperationType {
    
    private object itemField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("ignore", typeof(object))]
    [System.Xml.Serialization.XmlElementAttribute("mappings", typeof(MappingsType))]
    public object Item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/RuleSet.xsd", IncludeInSchema=false)]
public enum ItemChoiceType {
    
    /// <remarks/>
    and,
    
    /// <remarks/>
    or,
    
    /// <remarks/>
    selector,
}



and the xml I'm trying to deserialize
XML
<?xml version="1.0" encoding="utf-8" ?>
<ruleset xmlns="http://tempuri.org/RuleSet.xsd" supplierId="5" validFrom="2016-01-19">

  <rule>
    <selectors >
      <and>
        <selector column="ProdCode" select="begins-with" value="G1"/>
        <selector column="Product" select="equals" value="Gas"/>
      </and>
    </selectors>
    <operations>
      <operation>
        <mappings>
          <mapping>
            <adjustment operation="set" column="ContractType" value="New Business"/>
            <adjustment operation="set" column="Duration" value="1 year"/>
            <adjustment operation="set" column="FromCon" value="30000"/>
            <adjustment operation="set" column="ToCon" value="175000"/>
            <adjustment operation="add" column="rate" value="0.05"/>
          </mapping>
          <mapping>
            <adjustment operation="set" column="ContractType" value="Renewal"/>
            <adjustment operation="set" column="Duration" value="1 year"/>
            <adjustment operation="set" column="FromCon" value="45000"/>
            <adjustment operation="set" column="ToCon" value="175000"/>
            <adjustment operation="add" column="rate" value="0.03"/>
          </mapping>
        </mappings>
      </operation>
    </operations>
  </rule>

  <rule>
    <selectors >
      <and>
        <selector column="ProdCode" select="begins-with" value="G2"/>
        <selector column="Product" select="equals" value="Gas"/>
      </and>
    </selectors>
    <operations>
      <operation>
        <mappings>
          <mapping>
            <adjustment operation="set" column="ContractType" value="New Business"/>
            <adjustment operation="set" column="Duration" value="2 year"/>
            <adjustment operation="set" column="FromCon" value="18000"/>
            <adjustment operation="set" column="ToCon" value="175000"/>
            <adjustment operation="add" column="rate" value="0.09"/>
          </mapping>
          <mapping>
            <adjustment operation="set" column="ContractType" value="Renewal"/>
            <adjustment operation="set" column="Duration" value="2 year"/>
            <adjustment operation="set" column="FromCon" value="27000"/>
            <adjustment operation="set" column="ToCon" value="175000"/>
            <adjustment operation="add" column="rate" value="0.05"/>
          </mapping>
        </mappings>
      </operation>
    </operations>
  </rule>

  <rule>
    <selectors >
      <and>
        <selector column="ProdCode" select="begins-with" value="G3"/>
        <selector column="Product" select="equals" value="Gas"/>
      </and>
    </selectors>
    <operations>
      <operation>
        <mappings>
          <mapping>
            <adjustment operation="set" column="ContractType" value="New Business"/>
            <adjustment operation="set" column="Duration" value="3 year"/>
            <adjustment operation="set" column="FromCon" value="14000"/>
            <adjustment operation="set" column="ToCon" value="175000"/>
            <adjustment operation="add" column="rate" value="0.13"/>
          </mapping>
          <mapping>
            <adjustment operation="set" column="ContractType" value="Renewal"/>
            <adjustment operation="set" column="Duration" value="3 year"/>
            <adjustment operation="set" column="FromCon" value="19000"/>
            <adjustment operation="set" column="ToCon" value="175000"/>
            <adjustment operation="add" column="rate" value="0.07"/>
          </mapping>
        </mappings>
      </operation>
    </operations>
  </rule>

  <rule>
    <selectors >
      <and>
        <selector column="ProdCode" select="begins-with" value="PC"/>
        <selector column="Product" select="equals" value="Electricity"/>
      </and>
    </selectors>
    <operations>
      <operation>
        <mappings>
          <mapping>
            <adjustment operation="set" column="ContractType" value="New Business"/>
            <adjustment operation="set" column="Duration" value="1 year"/>
            <adjustment operation="set" column="FromCon" value="22000"/>
            <adjustment operation="set" column="ToCon" value="5000000"/>
            <adjustment operation="add" column="rate" value="0.08"/>
          </mapping>
        </mappings>
      </operation>
    </operations>
  </rule>

  <rule>
    <selectors >
      <and>
        <selector column="ProdCode" select="begins-with" value="TB"/>
        <selector column="Product" select="equals" value="Electricity"/>
      </and>
    </selectors>
    <operations>
      <operation>
        <mappings>
          <mapping>
            <adjustment operation="set" column="ContractType" value="New Business"/>
            <adjustment operation="set" column="Duration" value="1 year"/>
            <adjustment operation="set" column="FromCon" value="35000"/>
            <adjustment operation="set" column="ToCon" value="5000000"/>
            <adjustment operation="add" column="rate" value="0.05"/>
          </mapping>
          <mapping>
            <adjustment operation="set" column="ContractType" value="Renewal"/>
            <adjustment operation="set" column="Duration" value="1 year"/>
            <adjustment operation="set" column="FromCon" value="35000"/>
            <adjustment operation="set" column="ToCon" value="5000000"/>
            <adjustment operation="add" column="rate" value="0.03"/>
          </mapping>
        </mappings>
      </operation>
    </operations>
  </rule>

</ruleset>




Sorry for the long clips, but it all ties in together
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900