无法反序列化包含xsi:type属性的文档

时间:2013-01-20 15:57:16

标签: c#-4.0 xml-parsing xsd xsitype

解析XML文件时,我在serializer.Deserialize(reader)中出错: Namespace prefix \"java\" not defined

我的XML http://www.virtualdtm.ru/files/serverReplays/rFactorHotlapsData.xml

我的代码

var serializer = new XmlSerializer(typeof(rootDB));
var reader = new XmlTextReader(Server.MapPath(Url.Content("~/Content/xml/rFactorHotlapsData.xml")));
var rFactorHotLapsData = (rootDB)serializer.Deserialize(reader);

我的班级

//------------------------------------------------------------------------------
// <auto-generated>
//     Этот код создан программой.
//     Исполняемая версия:4.0.30319.17929
//
//     Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
//     повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;
namespace net.vmso.cpanel.Models.rFactorHotLaps
{
}

// 
// Этот исходный код был создан с помощью xsd, версия=4.0.30319.17929.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[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 rootDB {

    private rootDBListOfCategory[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("listOfCategory", Form=System.Xml.Schema.XmlSchemaForm.Qualified)]
    public rootDBListOfCategory[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rootDBListOfCategory {

    private string categoryNameField;

    private rootDBListOfCategoryListOfTrack[] listOfTrackField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string categoryName {
        get {
            return this.categoryNameField;
        }
        set {
            this.categoryNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("listOfTrack", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootDBListOfCategoryListOfTrack[] listOfTrack {
        get {
            return this.listOfTrackField;
        }
        set {
            this.listOfTrackField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rootDBListOfCategoryListOfTrack {

    private string trackNameField;

    private rootDBListOfCategoryListOfTrackSlowestLapRecord[] slowestLapRecordField;

    private rootDBListOfCategoryListOfTrackListOfLapRecord[] listOfLapRecordField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string trackName {
        get {
            return this.trackNameField;
        }
        set {
            this.trackNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("slowestLapRecord", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootDBListOfCategoryListOfTrackSlowestLapRecord[] slowestLapRecord {
        get {
            return this.slowestLapRecordField;
        }
        set {
            this.slowestLapRecordField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("listOfLapRecord", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public rootDBListOfCategoryListOfTrackListOfLapRecord[] listOfLapRecord {
        get {
            return this.listOfLapRecordField;
        }
        set {
            this.listOfLapRecordField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class rootDBListOfCategoryListOfTrackSlowestLapRecord {

    private string driverNameField;

    private string sessionNameField;

    private string dateField;

    private string vehicleModNameField;

    private string vehicleNameField;

    private string vehicleCategoryField;

    private string lapTimeField;

    private string lastLapTimeField;

    private string rankField;

    private string sessionIdField;

    private string lapCountField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string driverName {
        get {
            return this.driverNameField;
        }
        set {
            this.driverNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string sessionName {
        get {
            return this.sessionNameField;
        }
        set {
            this.sessionNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string date {
        get {
            return this.dateField;
        }
        set {
            this.dateField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string vehicleModName {
        get {
            return this.vehicleModNameField;
        }
        set {
            this.vehicleModNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string vehicleName {
        get {
            return this.vehicleNameField;
        }
        set {
            this.vehicleNameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string vehicleCategory {
        get {
            return this.vehicleCategoryField;
        }
        set {
            this.vehicleCategoryField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string lapTime {
        get {
            return this.lapTimeField;
        }
        set {
            this.lapTimeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string lastLapTime {
        get {
            return this.lastLapTimeField;
        }
        set {
            this.lastLapTimeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string rank {
        get {
            return this.rankField;
        }
        set {
            this.rankField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string sessionId {
        get {
            return this.sessionIdField;
        }
        set {
            this.sessionIdField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string lapCount {
        get {
            return this.lapCountField;
        }
        set {
            this.lapCountField = value;
        }
    }
}

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
    public partial class rootDBListOfCategoryListOfTrackListOfLapRecord {

        private string driverNameField;

        private string sessionNameField;

        private string dateField;

        private string vehicleModNameField;

        private string vehicleNameField;

        private string vehicleCategoryField;

        private string lapTimeField;

        private string lastLapTimeField;

        private string rankField;

        private string sessionIdField;

        private string lapCountField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string driverName {
            get {
                return this.driverNameField;
            }
            set {
                this.driverNameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string sessionName {
            get {
                return this.sessionNameField;
            }
            set {
                this.sessionNameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string date {
            get {
                return this.dateField;
            }
            set {
                this.dateField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string vehicleModName {
            get {
                return this.vehicleModNameField;
            }
            set {
                this.vehicleModNameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string vehicleName {
            get {
                return this.vehicleNameField;
            }
            set {
                this.vehicleNameField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string vehicleCategory {
            get {
                return this.vehicleCategoryField;
            }
            set {
                this.vehicleCategoryField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string lapTime {
            get {
                return this.lapTimeField;
            }
            set {
                this.lapTimeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string lastLapTime {
            get {
                return this.lastLapTimeField;
            }
            set {
                this.lastLapTimeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string rank {
            get {
                return this.rankField;
            }
            set {
                this.rankField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string sessionId {
            get {
                return this.sessionIdField;
            }
            set {
                this.sessionIdField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string lapCount {
            get {
                return this.lapCountField;
            }
            set {
                this.lapCountField = value;
            }
        }
    }

[1]:

1 个答案:

答案 0 :(得分:1)

未定义java命名空间前缀,但它用于.xml文档的xsi:type属性。如果添加一个将其定义到文档根目录的属性,则错误将消失。

<rootDB xmlns:java="http://tempuri3.org">

正如我们后来发现的那样,除此之外,xsi:type正在弄乱类的生成。不好。

使用XmlSerializer

<listOfTrack xsi:type="java:com.prorfactor.top100.database.Track">

默认名称空间中元素的名称为listOfTrack。但是它的类型在java前缀引用的命名空间中是com.prorfactor.top100.database.Track。发生这种情况是因为xsi:type属性更改了它。 xsd.exe可以解决这个问题,但需要一些帮助。

我开始工作的方法是创建两个.xsd。一个用于java命名空间,另一个用于文档的命名空间。他们互相导入。 作为一个例子,我将展示描述文档开头的位,其中名称和类型跳了很多。

<rootDB xmlns="http://tempuri2.org"
        xmlns:java="http://tempuri3.org">
  <listOfCategory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:type="java:com.prorfactor.top100.database.Category">
    <listOfTrack xsi:type="java:com.prorfactor.top100.database.Track">

对于我称为http://tempuri2.org的默认命名空间,架构必须列出元素的名称,因为它们位于默认命名空间中:

  <xs:element name="rootDB" >
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="listOfCategory" />
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <xs:element name="listOfCategory"
              type="java:com.prorfactor.top100.database.Category">
  </xs:element>

  <xs:element name="listOfTrack"
              type="java:com.prorfactor.top100.database.Track">
  </xs:element>

我命名为http://tempuri3.org的java命名空间的模式列出了使用xsi分配给元素的复杂类型:type:

  <xs:complexType name="com.prorfactor.top100.database.Category"
        xmlns:orig="http://tempuri2.org">
    <xs:sequence>
      <xs:element ref="orig:listOfTrack" minOccurs="0" maxOccurs="unbounded" />
      <xs:element ref="orig:categoryName"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="com.prorfactor.top100.database.Track"
        xmlns:orig="http://tempuri2.org">
    <xs:sequence>
      <xs:element ref="orig:slowestLapRecord" />
      <xs:element ref="orig:listOfLapRecord" minOccurs="0" maxOccurs="unbounded"/>
      <xs:element ref="orig:trackName"/>
    </xs:sequence>
  </xs:complexType>

我编译了这两个.xsd,生成的类设法反序列化.xml文件。

如果我手动添加java命名空间,并指定.xml文件的默认命名空间

所以,说实话,我认为你最好使用LINQ to XML:

使用LINQ to XML

XDocument xElement = XDocument.Load(Server.MapPath(Url.Content("~/Content/xml/rFactorHotlapsData.xml")));

// just some selects to show how you select them
var cats = from cat in xElement.Descendants("listOfCategory")
           select new
           {
              Name = cat.Descendants("categoryName").FirstOrDefault().Value,
              Track = from track in cat.Descendants("listOfTrack")
                      select new 
                      {
                         Name = track.Descendants("trackName").FirstOrDefault().Value,
                         LapRecord = from record in cat.Descendants("listOfLapRecord")
                                     select new
                                     {
                                        driverName = record.Descendants("driverName").FirstOrDefault().Value,
                                        sessionName = record.Descendants("sessionName").FirstOrDefault().Value,
                                        date = record.Descendants("date").FirstOrDefault().Value
                                     }
                       }
           };

// And a demo of how to iterate over the result of the select
foreach (var category in cats)
{
   Console.WriteLine(category.Name);
   foreach (var track in category.Track)
   {
      Console.WriteLine("  " + track.Name);
      foreach (var lapRecord in track.LapRecord)
      {
         Console.WriteLine("      " + lapRecord.driverName);
         Console.WriteLine("      " + lapRecord.sessionName);
         Console.WriteLine("      " + lapRecord.date);
      }
   }
}