简短的回答是你需要手动添加[XmlInclude(typeof(SequencePoint))] https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlincludeattribute.aspx给你的MethodPoint
class:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[XmlInclude(typeof(SequencePoint))]
public partial class CoverageSessionModulesModuleClassesClassMethodsMethodMethodPoint {
private string vcField;
private string uspidField;
private string ordinalField;
private string offsetField;
private string slField;
private string scField;
private string elField;
private string ecField;
private string becField;
private string bevField;
private string fileidField;
}
你还需要做SequencePoint
继承自MethodPoint
如果它还没有这样做的话。
你需要这样做是因为,当您使用 xsd.exe 从 XML 示例生成 XSD 时,然后依次是 c# 类,它显然不会在属性添加时自动将多态子类型属性添加到基类型中xsi:type="SomePolymoirphicSubType"
出现在 XML 中,尽管它看起来应该出现。
说明如下。这xsi:type
属性,简称{http://www.w3.org/2001/XMLSchema-instance}type
, is a w3c 标准属性 https://www.w3.org/TR/xmlschema-1/#xsi_type允许元素显式断言其类型,例如当它是预期元素类型的多态子类型时。XmlSerializer
支持该属性 https://msdn.microsoft.com/en-us/library/ca1ks327.aspx并将使用它来确定要为此类多态类型反序列化的对象的实际类型。但需要告知提前所有可能的类型使用XmlIncludeAttribute https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlincludeattribute.aspx。因此,如果我创建以下类型层次结构:
[XmlInclude(typeof(SequencePoint))]
public class MethodPoint
{
}
public class SequencePoint : MethodPoint
{
}
并将其序列化如下:
var test = new SequencePoint();
var serializer = new XmlSerializer(typeof(MethodPoint));
var sb = new StringBuilder();
using (var stream = new StringWriter(sb))
serializer.Serialize(stream, test);
Console.WriteLine(sb);
我得到以下 XML:
<MethodPoint
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xsi:type="SequencePoint" />
然后如果我使用反序列化它var serializer = new XmlSerializer(typeof(MethodPoint))
,我得到一个SequencePoint
,不是它的基类。如果我使用 xsd.exe 为这些类生成架构,我会得到:
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="MethodPoint" nillable="true" type="MethodPoint" />
<xs:complexType name="MethodPoint" />
<xs:complexType name="SequencePoint">
<xs:complexContent mixed="false">
<xs:extension base="MethodPoint" />
</xs:complexContent>
</xs:complexType>
<xs:element name="SequencePoint" nillable="true" type="SequencePoint" />
</xs:schema>
注意xs:extension
?这就是 XSD 指示多态子类型的方式。然后,如果我向后运行 xsd.exe 来重新生成我的类,我会得到:
[System.Xml.Serialization.XmlIncludeAttribute(typeof(SequencePoint))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
public partial class MethodPoint {
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
public partial class SequencePoint : MethodPoint {
}
如您所见,XmlIncludeAttribute
存在并且生成的类与原始类等效。到目前为止一切都很顺利。
但是,当从示例 XML 文件推断 XSD 时,xsd.exe 似乎没有识别出xsi:type
属性。例如,如果我从上面的简单 XML 创建 XSD,结果是:
<xs:schema id="MethodPoint" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="MethodPoint" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded" />
</xs:complexType>
</xs:element>
</xs:schema>
多态亚型完全缺失。从此 XSD 生成的类将无法反序列化该 XML。
因此,使用 xsd.exe 从 XML 示例生成 C# 类似乎不如从正确的 XSD 生成它们那么可靠。具体来说,在以下情况下xsi:type
如果出现在 XML 文件中,您将需要手动修复生成的类或生成的 XSD 以实现所需的层次结构。这可能是该工具的限制或错误。
(限制/错误也会出现在将 XML 粘贴为类 https://learn.microsoft.com/en-us/dotnet/framework/wcf/generating-data-type-classes-from-xml它使用xsd.exe
内部。)