我需要支持一个老旧的Visual Basic 6.0客户端,该客户端需要解析XML文件。这些文件由一个相当大而复杂的XSD模式描述。为了简化解析过程,我使用Windows SDK xsd.exe工具创建了C#类,并将其添加到C#库项目中,并设置了“使程序集COM可见”的属性。不幸的是,生成的类型库毫无价值,因为它仅为所有复杂类型公开空接口。
为了说明这种行为,请考虑以下XSD模式:
生成的类型库如下所示:
为了说明这种行为,请考虑以下XSD模式:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:customers" xmlns:c="urn:customers">
<xsd:element name="catalog" type="c:CatalogData"/>
<xsd:complexType name="AddressData">
<xsd:sequence>
<xsd:element name="no" type="xsd:integer"/>
<xsd:element name="road" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="CustomerData">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="address" type="c:AddressData"/>
<xsd:element name="order_date" type="xsd:date"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="CatalogData">
<xsd:sequence>
<xsd:element name="customer" type="c:CustomerData" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
工具会创建以下源文件:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System.Xml.Serialization;
//
// This source code was auto-generated by xsd, Version=4.0.30319.33440.
//
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:customers")]
[System.Xml.Serialization.XmlRootAttribute("catalog", Namespace="urn:customers", IsNullable=false)]
public partial class CatalogData {
private CustomerData[] customerField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("customer", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public CustomerData[] customer {
get {
return this.customerField;
}
set {
this.customerField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:customers")]
public partial class CustomerData {
private string nameField;
private AddressData addressField;
private System.DateTime order_dateField;
private string idField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public AddressData address {
get {
return this.addressField;
}
set {
this.addressField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="date")]
public System.DateTime order_date {
get {
return this.order_dateField;
}
set {
this.order_dateField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string id {
get {
return this.idField;
}
set {
this.idField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:customers")]
public partial class AddressData {
private string noField;
private string roadField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="integer")]
public string no {
get {
return this.noField;
}
set {
this.noField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string road {
get {
return this.roadField;
}
set {
this.roadField = value;
}
}
}
生成的类型库如下所示:
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: xsd.tlb
[
]
library xsd
{
importlib("mscorlib.tlb");
importlib("stdole2.tlb");
// Forward declare all types defined in this typelib
interface _CatalogData;
interface _CustomerData;
interface _AddressData;
[
]
coclass CatalogData {
[default] interface _CatalogData;
interface _Object;
};
[
]
coclass CustomerData {
[default] interface _CustomerData;
interface _Object;
};
[
]
coclass AddressData {
[default] interface _AddressData;
interface _Object;
};
[
]
interface _CatalogData : IDispatch {
};
[
]
interface _CustomerData : IDispatch {
};
[
]
interface _AddressData : IDispatch {
};
};
我知道,我可以手动创建所需的COM接口以公开所有嵌套属性。然而,由于复杂的XSD模式,生成的C#类文件超过3000行,如果要为每个部分类创建一个接口,将需要很长时间。
是否有一种替代方法可以加快进程?或者有人知道另一个工具,可以通过ATL或C ++从XSD模式生成COM接口/类?