引用通用类型的 XSD Gen 类
Posted
技术标签:
【中文标题】引用通用类型的 XSD Gen 类【英文标题】:XSD Gen Classes That Reference a Common Type 【发布时间】:2012-01-09 20:01:39 【问题描述】:我正在使用 XSD 在 C# 中定义我的 DTO 类型。我正在使用 XSD.exe 从 XSD 生成类。
我有一个定义地址类型的 Common.xsd,我想在多个类中使用它:
<xs:complexType name="Address">
<xs:sequence>
<xs:element name="Street1" type="xs:string"/>
<xs:element name="Street2" type="xs:string"/>
<xs:element name="City" type="xs:string"/>
<xs:element name="State" type="xs:string"/>
<xs:element name="Zip" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Address" type="mhm:Address"/>
我在公司 XSD 中引用了这个:
<xs:include schemaLocation=".\Common.xsd"/>
<xs:complexType name="Company">
<xs:sequence>
<xs:element name="AdmCode" type="xs:string"/>
<xs:element name="CompanyCode" type="xs:string"/>
<xs:element name="Name" type="xs:string"/>
<xs:element ref="mhm:Address"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Company" type="mhm:Company"/>
还有一个员工 XSD:
<xs:include schemaLocation=".\Common.xsd"/>
<xs:complexType name="Employee">
<xs:sequence>
<xs:element name="EmployeeNumber" type="xs:int"/>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="Address" type="mhm:Address"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Employee" type="mhm:Employee"/>
我使用这个命令行生成类:
xsd .\XSD\Common.xsd /c /o:. /n:"DomainModel"
xsd .\XSD\Employee.xsd /c /o:. /n:"DomainModel"
xsd .\XSD\Company.xsd /c /o:. /n:"DomainModel"
我去编译项目的时候发现在Company.cs类文件和Employee.cs类文件中都生成了Address类型。
如何在 Common.cs 类文件中获取只生成一次的 Address 类型,而 Employee 和 Company 类型使用这个单一的 Address 类型?
【问题讨论】:
【参考方案1】:您可以将XSD.exe
与多个文件参数一起使用:
xsd .\XSD\Common.xsd .\XSD\Employee.xsd .\XSD\Company.xsd /c /o:. /n:"DomainModel"
【讨论】:
谢谢马特 - 如果我尝试 xsd.exe 无法验证架构验证警告:全局元素“mhmr.com/domain/v1_0:A 地址”已被声明。第 20 行,位置 4。架构验证警告:complexType 'mhmr.com/domain/v1_0:Address' 已被声明。第 10 行,位置 4。架构验证警告:全局元素“mhmr.com/domain/v1_0:A 地址”已被声明。第 20 行,位置 4。 您可以尝试从命令行中排除“common.xsd”吗?我认为由于它是通过 XSD 包含的,您可能不需要在命令行中传递它。 实际上,您的第一个答案是正确的。所有的类都被生成到命令行中的最后一个 xsd 类中。我看代码的距离不够近,并且在尝试重新编译之前没有删除其他类文件。加分(!)您知道如何将每种 C# 类型生成到其自己的类文件中吗? ***.com/questions/8315129/… @RobertMS 回答您关于拆分文件的问题,请参阅我的回答。【参考方案2】:您基本上希望将常用类型拆分为一个公共程序集,该程序集由您的其他类型引用。你有两个选择:
-
手动拆分它们。我知道这是一个生成的文件,但如果你的源模式是相当静态的,那么这是一个一次性的练习。
请改用 svcutil.exe。然而,这要复杂得多,实际上你甚至可能无法做到这一点,除非你的模式都遵守某些准则。如果您有兴趣,请参阅下面的流程。
如果您喜欢上面的选项 2,那么这里是一般过程:
-
使用 svcutil 上的 /dconly 标志从 Common.xsd 中提取类型。这将生成一个包含常用类型的类文件。
将此类编译成程序集
使用 /r 标志从 A.xsd 中提取类型并引用您的 CommonTypes.dll 程序集。
对 B.xsd 执行相同操作
但是,此方法基于 svcutil 使用 DataContractSerializer 来完成工作,因为 /r 标志对 XmlSerializer 不可用。这只有在您的模式遵守相当严格的 DCS 规则时才有效(可以在此处找到:http://msdn.microsoft.com/en-us/library/ms733112.aspx)。
如果不遵守这些规则,那么 svcutil 将回退到使用不支持 /r 标志的 XmlSerializer。
【讨论】:
谢谢休。将所有生成的类放在一个代码文件中并不是什么大问题,因为它们是生成的,因此我不会直接接触它们,但会编辑 xsd。我实际上会将代码生成作为构建步骤。以上是关于引用通用类型的 XSD Gen 类的主要内容,如果未能解决你的问题,请参考以下文章