如何避免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
相关产品推荐
相关产品推荐

