尝试反序列化XML文件

时间:2013-11-23 16:26:38

标签: c# xml serialization xsd

我使用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架构中指定人员的方式。

我应该改变班级的某些内容吗?我应该添加一些属性还是别的什么?

我不知道如何解决此错误!

1 个答案:

答案 0 :(得分:0)

三点建议:

  1. 使用xsi作为名称空间前缀 http://www.w3.org/2001/XMLSchema-instance。这不是必需的 但这是标准的。
  2. 对路径中包含空格的本地XSD使用以下语法: file:///C:/Users/SIGFRID/Documents/Visual%20Studio%202012/Projects/sample/ConsoleApplication1/ConsoleApplication1/MySample.xsd
  3. 使用xsi:noNamespaceSchemaLocation而不是xsi:schemaLocation 因为你没有使用名称空间。
  4. 以下是适用这些建议的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>