我使用xsd.exe生成了以下类:
using System.Xml.Serialization;
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class ROOT {
private PersonBaseType pERSONField;
/// <remarks/>
public PersonBaseType PERSON {
get {
return this.pERSONField;
}
set {
this.pERSONField = value;
}
}
}
[System.Xml.Serialization.XmlIncludeAttribute(typeof(NotWorkerPersonType))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(WorkerPersonType))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public abstract partial class PersonBaseType {
private MotorVehicleType vEHICLEField;
public MotorVehicleType VEHICLE {
get {
return this.vEHICLEField;
}
set {
this.vEHICLEField = value;
}
}
}
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CarVehicleType))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(AutobusVehicleType))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public abstract partial class MotorVehicleType {
private string nameField;
public string Name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class CarVehicleType : MotorVehicleType {
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class AutobusVehicleType : MotorVehicleType {
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class NotWorkerPersonType : PersonBaseType {
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class WorkerPersonType : PersonBaseType {
}
我使用xsd.exe工具和以下xsd架构生成了这个类:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" elementFormDefault="qualified" attributeFormDefault="qualified">
<xsd:complexType name="PersonBaseType" abstract="true">
<xsd:sequence>
<xsd:element name="VEHICLE" type="MotorVehicleType" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="WorkerPersonType">
<xsd:complexContent>
<xsd:restriction base="PersonBaseType">
<xsd:sequence>
<xsd:element name="VEHICLE" type="AutobusVehicleType" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="NotWorkerPersonType">
<xsd:complexContent>
<xsd:restriction base="PersonBaseType">
<xsd:sequence>
<xsd:element name="VEHICLE" type="CarVehicleType" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="MotorVehicleType" abstract="true">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="AutobusVehicleType">
<xsd:complexContent>
<xsd:restriction base="MotorVehicleType">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="CarVehicleType">
<xsd:complexContent>
<xsd:restriction base="MotorVehicleType">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="ROOT">
<xsd:annotation>
<xsd:documentation>Root element</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="PERSON" type="PersonBaseType" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
我尝试反序列化这个xml:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT xmlns:xxx="http://www.w3.org/2001/XMLSchema-instance" xxx:schemaLocation="C:\Users\SIGFRID\Documents\Visual Studio 2012\Projects\sample\ConsoleApplication1\ConsoleApplication1\MySample.xsd">
<PERSON xxx:type="WorkerPersonType">
<VEHICLE>
<Name>VOLVO</Name>
</VEHICLE>
</PERSON>
</ROOT>
架构验证是正确的,我没有问题,但随后我收到一条InvalidOperationException
消息:
The specified type is abstract: name='MotorVehicleType', Namespace='', bei <VEHICLE xmlns=''>."}
我知道我应该指定VEHICLE的类型,但为什么xml会通过架构验证?如果Person元素是WorkerPersonType,则VEHICLE只能是AutobusVehicleType。这就是我在xsd架构中指定人员的方式。
我应该改变班级的某些内容吗?我应该添加一些属性还是别的什么?
我不知道如何解决此错误!
答案 0 :(得分:0)
三点建议:
xsi
作为名称空间前缀
http://www.w3.org/2001/XMLSchema-instance
。这不是必需的
但这是标准的。file:///C:/Users/SIGFRID/Documents/Visual%20Studio%202012/Projects/sample/ConsoleApplication1/ConsoleApplication1/MySample.xsd
xsi:noNamespaceSchemaLocation
而不是xsi:schemaLocation
因为你没有使用名称空间。以下是适用这些建议的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="file:///C:/Users/SIGFRID/Documents/Visual%20Studio%202012/Projects/sample/ConsoleApplication1/ConsoleApplication1/MySample.xsd">
<PERSON xsi:type="WorkerPersonType">
<VEHICLE>
<Name>VOLVO</Name>
</VEHICLE>
</PERSON>
</ROOT>