我有一个XML架构文件(xsd(,它序列化为一个文件,这正是我需要文件的外观和行为方式。 但是,我想要的是一个顶级元素,特别是标头,被实例化。 现在,XSD生成的源代码.exe 只是为我提供了一个键入为标头对象的"Header"属性,但它没有实例化。
专门使用 System.XML.Serialization 将对象从 XML 文件序列化为类型化对象。
所以基本上,如果我尝试...
MyDoc.Header.HeaderField1 = "My value";
我收到一个空引用错误。
我必须...
MyDoc.Header = new MyApplication.Models.MyDoc.Header();
MyDoc.Header.HeaderField1 = "My value";
我希望能够简单地让 XSD.exe 工具生成 Header 对象,并在 Header 属性中,直接从蝙蝠开始将值设置为 = new Header((。
没什么大不了的,很容易解决,但可以更整洁。 :-p
这基本上是我拥有的架构。
<?xml version="1.0" encoding="utf-8"?>
<!--
xsd MyDoc.xsd /c /n:MyApplication.Models
-->
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsd:element name="MyDoc">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Header">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="HeaderField1" type="xsd:string" />
<xsd:element name="HeaderField2" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Items">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="Item">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Field1" type="xsd:string" />
<xsd:element name="Field2" type="xsd:string" />
<xsd:element name="Field3" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xs:schema>
我发现解决这个问题的最佳方法是简单地在代码中为 MyDoc 添加新的分部类。
所以我最终得到了 XSD.exe 创建的生成的 C# MyDoc.cs 文件。 然后我创建了一个名为MyDocPartial.cs的新类文件。 在那个,它看起来像...
namespace MyApplication.Models
{
public partial class MyDoc
{
public MyDoc()
{
this.Header = new MyDocHeader();
}
}
}
有一个单独的分部类 MyDoc 由 XSD.exe 生成。 但是,它没有定义的构造函数。 想想我只是在这里放屁,但也想我会为其他人分享。 :)
请注意,这个分部类也是我放入所有字段映射代码、简化添加项的代码等的地方。 全脑屁。 希望对您有所帮助。 :)
我创建了一个正则表达式搜索/替换模式,用于自动转换所有属性获取者:
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public AmountType TaxableBase {
get {
return this.taxableBaseField;
}
set {
this.taxableBaseField = value;
}
}
对此:
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public AmountType TaxableBase {
get {
if(this.taxableBaseField == null) this.taxableBaseField = new AmountType();
return this.taxableBaseField;
}
set {
this.taxableBaseField = value;
}
}
要使用它,请打开搜索/替换为 Ctrl+H,选中 .* 类型,取消选中其他类型,将范围设置为当前文档。在搜索框中写下这个模式:
(public )(S+Type)( S+ {rn +get {rn)( +)(return )(this.S+);
这个在替换框中:
$1$2$3$4if($6 == null) $6 = new $2();rn$4$5$6;
首先,您可以尝试逐个替换。如果有效,请点击全部替换。
如果 xsd 的类中有枚举类型,它将在错误面板中显示警告,告诉您它们不能等于 null (CS0472(.
您可以双击每个警告,然后按 Ctrl+X 剪切焦点代码行。您无需移动鼠标,只需双击并重复按 Ctrl+X。删除所有这些内容的速度很快。
它非常适合我的 xsd。您可能必须修改正则表达式模式以匹配您的类型。特别是S+Type
部分。我用它来区分字符串等。