任何方式来覆盖xsd.exe </choice>绑定<choice>元素的方式

时间:2010-04-15 15:27:45

标签: xsd xsd.exe

我的架构中有以下元素:

<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>

在我的主模式体中,我使用一个元素来指定1的情况:

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

运行xsd.exe时,生成的代码为:

    [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;
        }
    }

问题是元素的ID标记被忽略,xsd.exe任意命名属性“Item”。我不得不承认,这不是一个大问题,但它开始惹恼我。更令人讨厌的是,如果我在同一级别有其他元素,xsd.exe会将它们绑定为“Item1”,“Item2”等。

有没有人知道是否可以让xsd.exe将我的选择元素命名为“Item”,而是能够放入我自己的属性名称?

5 个答案:

答案 0 :(得分:3)

我搜索过高和低,但似乎没有解决我的问题。根据链接:

http://msdn.microsoft.com/en-us/library/sa6z5baz(VS.80).aspx 似乎选择元素的任意命名是可重写。希望这些信息对其他人有帮助......!

答案 1 :(得分:0)

我曾经实际解析过自动生成的xsd.exe文件,并使用NRefactory更改了它。

答案 2 :(得分:0)

我自己在与XSD.exe打交道时遇到了这个限制。对于XSD.exe如何解释所有元素类型的ID属性,这似乎是一个相当统一的做法。我很想听听MS开发团队中有人为什么XSD.exe以这种方式工作的合理化。有趣的是,我一直在研究SchemaImporterExtension,除其他外,它将利用选择元素的ID属性来精确地实现您所描述的内容,这是一种自定义选择映射对象成员的字段/属性名称的方法。不幸的是,不仅XSD.exe似乎不支持ID属性绑定,而且甚至看不到ID包含在XmlSchemaChoice对象中,该对象反映了已解析的模式文档中的choice元素。也许我错过了一些东西,但如果这确实是预期的行为并且不是我的错误,那么在我的估计中这是一个相当荒谬的遗漏,它说明了在MS中反映了多少绝育的XSD表示。模式自动生成工具。 XSD.exe坚持我所说的XML模式标准的“精益和平均”解释。显然现在WCF避免使用XSD.exe,猜猜是什么? WCF的svcutil工具可识别XML模式的偶数较小占用空间; svcutil IIRC甚至不支持选择元素绑定。在某些时候,我甚至不确定MS自动生成工具将带来什么价值,因为你将被简化为使用简单的XSD结构(我的意思是,没有选择元素支持?真的吗?)封装业务对象建模。

答案 3 :(得分:0)

今天遇到了这个问题。

我确实有一个解决方法,因此您可以使用组而不是选择来规避此问题。

使用上面的xsd作为基础:

重写:

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

要:

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

引用元素中的组:

<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>

运行xsd.exe,结果如下

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;
        }
    }
}

现在你有了属性名称RiskModel和FullCovariance

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

f.FullCovariance.fromDate

如果您需要多个RiskModels和FullCovariance对象项,则可以在序列中添加具有RiskModelGroup的新元素。

祝你好运!

答案 4 :(得分:0)

对于那些仍然想知道的人:只需使用XSDObjectGenerator(由Microsoft制作)。它通过为您的类添加一个对象来管理XsdChoice。这样,您就不必寻找用于Item属性的正确元素。 例如:

<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>

成了

[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));
    }
}