You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免XSD.EXE生成C#代码时将嵌套类型折叠为锯齿数组?

保留XSD生成C#代码中的嵌套容器类型(避免转为锯齿数组)

给定如下XSD文件(test.xsd):

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="ContainingClass" type="ContainingClass" />

  <xs:complexType name="ContainingClass">
    <xs:sequence>
      <xs:element name="OuterArrayContainer" type="OuterArrayContainer" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="OuterArrayContainer">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="10" name="OuterArray" type="InnerArrayContainer" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="InnerArrayContainer">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="10" name="InnerArray" type="xs:int" />
    </xs:sequence>
  </xs:complexType>

</xs:schema>

执行命令 xsd test.xsd /c 生成C#代码时,嵌套容器类型会被自动扁平化,转为int[][]锯齿数组,直接丢失OuterArrayContainer和InnerArrayContainer类型:

public partial class ContainingClass {

    private int[][] outerArrayContainerField;

    public int[][] OuterArrayContainer {
        get { return this.outerArrayContainerField; }
        set { this.outerArrayContainerField = value; }
    }
}

添加虚拟元素虽能保留类型,但会生成无用属性,以下是无需冗余元素、无需手动修改生成代码的解决方案:


解决方案:给容器类型添加可选固定属性

给每个容器类型添加一个可选的固定值属性,让XSD.exe识别到这是包含额外标识的复杂类型,从而保留类定义,且该属性不会影响实际使用。

修改后的XSD如下:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="ContainingClass" type="ContainingClass" />

  <xs:complexType name="ContainingClass">
    <xs:sequence>
      <xs:element name="OuterArrayContainer" type="OuterArrayContainer" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="OuterArrayContainer">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="10" name="OuterArray" type="InnerArrayContainer" />
    </xs:sequence>
    <!-- 添加可选固定属性,避免类型被扁平化 -->
    <xs:attribute name="containerType" type="xs:string" fixed="outer" use="optional"/>
  </xs:complexType>

  <xs:complexType name="InnerArrayContainer">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="10" name="InnerArray" type="xs:int" />
    </xs:sequence>
    <!-- 添加可选固定属性,避免类型被扁平化 -->
    <xs:attribute name="containerType" type="xs:string" fixed="inner" use="optional"/>
  </xs:complexType>

</xs:schema>

再次执行 xsd test.xsd /c 后,生成的C#代码会完整保留所有嵌套类型:

public partial class ContainingClass {

    private OuterArrayContainer outerArrayContainerField;

    public OuterArrayContainer OuterArrayContainer {
        get { return this.outerArrayContainerField; }
        set { this.outerArrayContainerField = value; }
    }
}

public partial class OuterArrayContainer {

    private InnerArrayContainer[] outerArrayField;
    private string containerTypeField;

    [System.Xml.Serialization.XmlElementAttribute("OuterArray", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public InnerArrayContainer[] OuterArray {
        get { return this.outerArrayField; }
        set { this.outerArrayField = value; }
    }

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string containerType {
        get { return this.containerTypeField; }
        set { this.containerTypeField = value; }
    }
}

public partial class InnerArrayContainer {

    private int[] innerArrayField;
    private string containerTypeField;

    [System.Xml.Serialization.XmlElementAttribute("InnerArray", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public int[] InnerArray {
        get { return this.innerArrayField; }
        set { this.innerArrayField = value; }
    }

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string containerType {
        get { return this.containerTypeField; }
        set { this.containerTypeField = value; }
    }
}
  • 该可选属性在实际使用时可完全忽略,不需要赋值,XML序列化/反序列化时也不会强制要求存在,完全不影响原有业务逻辑。

内容的提问来源于stack exchange,提问作者Matthew Watson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:57:49