3

I have the following elements in my schema:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="optimizeModelBase">
    <xs:attribute name="name" type="xs:string"/>
  </xs:complexType>

  <xs:complexType name="riskModel">
    <xs:complexContent>
      <xs:extension base="optimizeModelBase">
        <xs:attribute name="type" type="xs:string" use="required"/>        
      </xs:extension>      
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="fullCovariance">
    <xs:complexContent>
      <xs:extension base="optimizeModelBase">
        <xs:attribute name="fromDate" type="xs:date" use="required"/>
        <xs:attribute name="toDate" type="xs:date" use="required"/>
        <xs:attribute name="windowSize" type="xs:int" use="required"/>
      </xs:extension>
    </xs:complexContent>    
  </xs:complexType>

In my main schema body, I use a element to specify a 1-of situation:

<xs:choice id="RiskModelParameter">
  <xs:element name="RiskModel" type="riskModel"/>
  <xs:element name="FullCovariance" type="fullCovariance"/>
</xs:choice>

When I run xsd.exe, the resulting code is:

    [System.Xml.Serialization.XmlElementAttribute("FullCovariance",
    typeof(fullCovariance))]
    [System.Xml.Serialization.XmlElementAttribute("RiskModel", 
    typeof(riskModel))]
    public optimizeModelBase Item 
    {
        get 
        {
           return this.itemField;
        } 
        set 
        {
            this.itemField = value;
        }
    }

The issue is that the element's ID tag is being ignored, and xsd.exe is arbitrarily naming the property "Item". I have to admit, it's not a big issue, but it's starting to annoy me. What makes this extra annoying is that if I have additional elements at the same level, xsd.exe binds them as "Item1", "Item2", etc.

Does anyone know if it's possible to not have xsd.exe name my choice elements as "Item", and instead be able to put in my own property names?

code4life
  • 15,655
  • 7
  • 50
  • 82

5 Answers5

3

I've searched high and low, but it seems like there is no solution for my problem. According to the link:

http://msdn.microsoft.com/en-us/library/sa6z5baz(VS.80).aspx It seems like the arbitrary naming of the choice element is not overrideable. Hopefully this information is helpful to others out there...!

code4life
  • 15,655
  • 7
  • 50
  • 82
1

Just had this exact problem today.

I do have a workaround so you can circumvent this problem using a group instead of choice.

using the above xsd as the basis:

Rewrite:

<xs:choice id="RiskModelParameter">
  <xs:element name="RiskModel" type="riskModel"/>
  <xs:element name="FullCovariance" type="fullCovariance"/>
</xs:choice>

To:

<xs:group name="RiskModelGroup">
    <xs:sequence>
        <xs:element name="RiskModel" type="riskModel"/>
        <xs:element name="FullCovariance" type="fullCovariance"/>
    </xs:sequence>
</xs:group>

Reference the group in your element:

<xs:element name="Foo">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="SomeFieldId" type="xs:int" />
      <xs:group ref="RiskModelGroup" minOccurs="1" maxOccurs="1"/>
    </xs:sequence>
    </xs:complexType>
</xs:element>

Run xsd.exe and the result is as follows

public partial class Foo {

    private int someFieldIdField;

    private riskModel riskModelField;

    private fullCovariance fullCovarianceField;

    /// <remarks/>
    public int SomeFieldId {
        get {
            return this.someFieldIdField;
        }
        set {
            this.someFieldIdField = value;
        }
    }

    /// <remarks/>
    public riskModel RiskModel {
        get {
            return this.riskModelField;
        }
        set {
            this.riskModelField = value;
        }
    }

    /// <remarks/>
    public fullCovariance FullCovariance {
        get {
            return this.fullCovarianceField;
        }
        set {
            this.fullCovarianceField = value;
        }
    }
}

Now you have property names RiskModel and FullCovariance

Foo f = new Foo()
f.RiskModel.name

or

f.FullCovariance.fromDate

If you require multiple Items of RiskModels and FullCovariance objects you could add a new element having the RiskModelGroup within a sequence.

Good luck!

Marlon Navas
  • 121
  • 1
  • 3
  • Thanks, but I really need to send only one or the other xml node. The server side does a switch based on the form of the xml. So sending both nodes (even if one is nilled) won't work. – code4life Jul 06 '13 at 13:00
1

For those who still want to know : Just use XSDObjectGenerator (made by Microsoft). It manage XsdChoice by adding one object for each choice to your class. That way, you don't have to look for the right element to use for the Item property. For example:

<xs:complexType name="AccountSchemeName1Choice">
    <xs:sequence>
        <xs:choice>
            <xs:element name="Cd" type="ExternalAccountIdentification1Code"/>
            <xs:element name="Prtry" type="Max35Text"/>
        </xs:choice>
    </xs:sequence>
</xs:complexType>

became

[XmlType(TypeName = "AccountSchemeName1Choice", Namespace = Declarations.SchemaVersion), Serializable]
public class AccountSchemeName1Choice : INotifyPropertyChanged
{

    [XmlElement(ElementName = "Cd", IsNullable = false, Form = XmlSchemaForm.Qualified, DataType = "string", Namespace = Declarations.SchemaVersion)]
    public string __Cd;

    [XmlIgnore]
    public string Cd
    {
        get { return __Cd; }
        set { __Cd = value; RaisePropertyChanged("Cd"); }
    }

    [XmlElement(ElementName = "Prtry", IsNullable = false, Form = XmlSchemaForm.Qualified, DataType = "string", Namespace = Declarations.SchemaVersion)]
    public string __Prtry;

    [XmlIgnore]
    public string Prtry
    {
        get { return __Prtry; }
        set { __Prtry = value; RaisePropertyChanged("Prtry"); }
    }

    public AccountSchemeName1Choice()
    {
    }

    [field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
SeyoS
  • 661
  • 5
  • 22
0

I once actually parsed an autogenerated xsd.exe file and changed it using NRefactory.

Orentet
  • 2,353
  • 1
  • 17
  • 28
0

I myself just encountered this limitation in my dealings with XSD.exe. It seems that this is a fairly uniform practice with respect to how XSD.exe interprets the ID attribute for all element types. I'd love to hear a rationalization from someone on the MS development team for why XSD.exe works in this manner.

What's interesting is that I have been working on a SchemaImporterExtension that would, among other things, leverage the ID attribute of choice elements to achieve precisely what you're describing, a means of customizing the field/property names of choice mapped object members.

Unfortunately, not only does it seem that XSD.exe doesn't support ID attribute binding, but it doesn't even appear that ID is included in the XmlSchemaChoice object that reflects the choice element from the parsed schema document.

Perhaps I'm missing something, but if this is indeed the intended behavior and not an error on my part, then it's a pretty ridiculous omission in my estimation, and it speaks to just how much of a neutered XSD representation is reflected in the MS schema auto-generation tools.

XSD.exe adheres to what I'll term as a "lean and mean" interpretation of the XML schema standard. Apparently now WCF obviates XSD.exe, and guess what? WCF's svcutil tool recognizes an even smaller footprint of XML schema; choice element binding is even't supported in svcutil IIRC.

At some point I'm not even sure what value the MS auto-generation tools are going to bring to the table, because you're going to be reduced to using trivial XSD structures (I mean, no choice element support? Really?) to encapsulate your business object modeling.

George Birbilis
  • 2,782
  • 2
  • 33
  • 35
Mike
  • 9
  • 1
  • 2
    wall of text! not entirely clear immediately whether this answers the question or not. I suggest you add some formatting, paragraphs, headings etc to make it more readable – Tim Abell Jul 15 '16 at 10:26
  • formatted the wall of text so that I could read it, so here it is – George Birbilis Nov 13 '20 at 16:53